diff --git a/BetaCameras/Sick.VisionaryT.Pro/CameraModel.cs b/BetaCameras/Sick.VisionaryT.Pro/CameraModel.cs
new file mode 100644
index 00000000..038338d2
--- /dev/null
+++ b/BetaCameras/Sick.VisionaryT.Pro/CameraModel.cs
@@ -0,0 +1,55 @@
+// Copyright (c) Metrilus GmbH
+// MetriCam 2 is licensed under the MIT license. See License.txt for full license text.
+using Newtonsoft.Json;
+
+namespace MetriCam2.Cameras.Internal.Sick
+{
+ class CameraObject
+ {
+ [JsonProperty(PropertyName = "class")]
+ public string CameraClass { get; set; }
+
+ public CameraData Data { get; set; }
+ }
+
+ class CameraData
+ {
+ public string CameraID { get; set; }
+ public int ImageWidth { get; set; }
+ public int ImageHeight { get; set; }
+ public float FocalDistance { get; set; }
+ public string FocalDistanceUnit { get; set; }
+ public float[][] IntrinsicK { get; set; }
+ public float[][] WorldToSensorDistortion { get; set; }
+ public float[][] SensorToWorldDistortion { get; set; }
+ public float[][] WorldToView { get; set; }
+ public Point PixelSize { get; set; }
+ public Point Origin { get; set; }
+ public string HandleZeroPixels { get; set; }
+ public ImageData Data { get; set; }
+ }
+
+ class ImageData
+ {
+ public string ImageType { get; set; }
+ public int Width { get; set; }
+ public int Height { get; set; }
+ public Pixels Pixels { get; set; }
+ }
+
+ class Pixels
+ {
+ public int numOfElems { get; set; }
+ public int elemSz { get; set; }
+ public string endian { get; set; }
+ public string[] elemTypes { get; set; }
+ public string data { get; set; }
+ }
+
+ class Point
+ {
+ public int x { get; set; }
+ public int y { get; set; }
+ public int z { get; set; }
+ }
+}
diff --git a/BetaCameras/Sick.VisionaryT.Pro/Properties/AssemblyInfo.cs b/BetaCameras/Sick.VisionaryT.Pro/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..82f9a647
--- /dev/null
+++ b/BetaCameras/Sick.VisionaryT.Pro/Properties/AssemblyInfo.cs
@@ -0,0 +1,20 @@
+// Copyright (c) Metrilus GmbH
+// MetriCam 2 is licensed under the MIT license. See License.txt for full license text.
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MetriCam 2: SICK Visionary-T-Pro wrapper")]
+[assembly: AssemblyDescription("MetriCam 2 wrapper for SICK Visionary-T-Pro cameras")]
+[assembly: MetriCam2.Attributes.ContainsCameraImplementations]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("658d0052-ccd1-4b52-9af9-6c0ece90cd3e")]
diff --git a/BetaCameras/Sick.VisionaryT.Pro/Properties/Resources.Designer.cs b/BetaCameras/Sick.VisionaryT.Pro/Properties/Resources.Designer.cs
new file mode 100644
index 00000000..e9fcb4f4
--- /dev/null
+++ b/BetaCameras/Sick.VisionaryT.Pro/Properties/Resources.Designer.cs
@@ -0,0 +1,73 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace MetriCam2.Cameras.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ public class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MetriCam2.Cameras.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
+ ///
+ public static System.Drawing.Icon SickIcon {
+ get {
+ object obj = ResourceManager.GetObject("SickIcon", resourceCulture);
+ return ((System.Drawing.Icon)(obj));
+ }
+ }
+ }
+}
diff --git a/BetaCameras/Sick.VisionaryT.Pro/Properties/Resources.resx b/BetaCameras/Sick.VisionaryT.Pro/Properties/Resources.resx
new file mode 100644
index 00000000..3d12a2df
--- /dev/null
+++ b/BetaCameras/Sick.VisionaryT.Pro/Properties/Resources.resx
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ ..\SickIcon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
\ No newline at end of file
diff --git a/BetaCameras/Sick.VisionaryT.Pro/Sick.VisionaryT.Pro.csproj b/BetaCameras/Sick.VisionaryT.Pro/Sick.VisionaryT.Pro.csproj
new file mode 100644
index 00000000..be9f3dff
--- /dev/null
+++ b/BetaCameras/Sick.VisionaryT.Pro/Sick.VisionaryT.Pro.csproj
@@ -0,0 +1,97 @@
+
+
+
+
+
+ Debug
+ x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}
+ Library
+ Properties
+ MetriCam2.Cameras
+ MetriCam2.Cameras.Sick.VisionaryT.Pro
+ v4.5
+ 512
+
+
+
+ true
+ ..\..\bin\x64\Debug\
+ DEBUG;TRACE
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+ true
+ false
+
+
+ ..\..\bin\x64\Release\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+ true
+ false
+
+
+
+ $(LibrariesPath)Metrilus.Util.dll
+
+
+ False
+ $(LibrariesPath)Newtonsoft.Json.dll
+
+
+
+
+
+
+
+
+
+
+
+
+ SolutionAssemblyInfo.cs
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+
+ {342f049e-668b-4351-b21d-75e4bef5a1e4}
+ MetriCam2
+
+
+
+
+ .licenseheader
+
+
+
+
+ PublicResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BetaCameras/Sick.VisionaryT.Pro/SickIcon.ico b/BetaCameras/Sick.VisionaryT.Pro/SickIcon.ico
new file mode 100644
index 00000000..09841e09
Binary files /dev/null and b/BetaCameras/Sick.VisionaryT.Pro/SickIcon.ico differ
diff --git a/BetaCameras/Sick.VisionaryT.Pro/VisionaryTPro.cs b/BetaCameras/Sick.VisionaryT.Pro/VisionaryTPro.cs
new file mode 100644
index 00000000..9e1435b2
--- /dev/null
+++ b/BetaCameras/Sick.VisionaryT.Pro/VisionaryTPro.cs
@@ -0,0 +1,410 @@
+// Copyright (c) Metrilus GmbH
+// MetriCam 2 is licensed under the MIT license. See License.txt for full license text.
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using Newtonsoft.Json;
+using Metrilus.Util;
+using MetriCam2.Exceptions;
+using MetriCam2.Cameras.Internal.Sick;
+
+namespace MetriCam2.Cameras
+{
+ ///
+ /// MetriCam2 wrapper for Sick Visionary-T Pro cameras.
+ ///
+ public class VisionaryTPro : Camera
+ {
+ #region Types
+ private class InverseBrownConradyParams
+ {
+ public float Fx { get; set; }
+ public float Fy { get; set; }
+ public float Cx { get; set; }
+ public float Cy { get; set; }
+ public float K1 { get; set; }
+ public float K2 { get; set; }
+ public float K3 { get; set; }
+ public float P1 { get; set; }
+ public float P2 { get; set; }
+ }
+ #endregion
+
+ private Thread _updateThread;
+ private Socket _socket;
+ private char[] _frontJsonData = null;
+ private char[] _backJsonData = null;
+ private int _intensityJsonOffset;
+ private int _intensityJsonSize;
+ private int _distanceJsonOffset;
+ private int _distanceJsonSize;
+ private int _imageHeight = 0;
+ private int _imageWidth = 0;
+ private AutoResetEvent _frameAvailable = new AutoResetEvent(false);
+ private CancellationTokenSource _cancelUpdateThreadSource;
+ private Point3fCameraImage _directions = null;
+ private const int NumFrameRetries = 3;
+ private string _updateThreadError = null;
+ private Exception _updateThreadException = null;
+
+ private ParamDesc IPAddressDesc
+ {
+ get
+ {
+ return new ParamDesc()
+ {
+ Description = "IP address",
+ ReadableWhen = ParamDesc.ConnectionStates.Disconnected | ParamDesc.ConnectionStates.Connected,
+ WritableWhen = ParamDesc.ConnectionStates.Disconnected
+ };
+ }
+ }
+
+ public string IPAddress { get; set; }
+
+
+ private ParamDesc PortDesc
+ {
+ get
+ {
+ return new ParamDesc()
+ {
+ Description = "Port",
+ ReadableWhen = ParamDesc.ConnectionStates.Disconnected | ParamDesc.ConnectionStates.Connected,
+ WritableWhen = ParamDesc.ConnectionStates.Disconnected
+ };
+ }
+ }
+ public int Port { get; set; } = 2115;
+
+#if !NETSTANDARD2_0
+ public override Icon CameraIcon => Properties.Resources.SickIcon;
+#endif
+
+ public VisionaryTPro()
+ : base()
+ {
+
+ }
+
+ #region MetriCam2 Camera Interface
+
+ public override string Name { get => "Visionary-T-Pro"; }
+ public override string Vendor { get => "Sick"; }
+
+ protected override void LoadAllAvailableChannels()
+ {
+ ChannelRegistry cr = ChannelRegistry.Instance;
+
+ Channels.Clear();
+
+ Channels.Add(cr.RegisterChannel(ChannelNames.Intensity));
+ Channels.Add(cr.RegisterChannel(ChannelNames.Distance));
+ Channels.Add(cr.RegisterChannel(ChannelNames.Point3DImage));
+ }
+
+
+ protected override void ConnectImpl()
+ {
+ _updateThreadError = null;
+ _updateThreadException = null;
+ _updateThread = new Thread(new ThreadStart(UpdateLoop));
+ _cancelUpdateThreadSource = new CancellationTokenSource();
+
+ if (string.IsNullOrEmpty(IPAddress))
+ {
+ string msg = string.Format("IP address is not set. It must be set before connecting.");
+ log.Error(msg);
+ throw ExceptionBuilder.Build(typeof(ConnectionFailedException), Name, "error_connectionFailed", msg);
+ }
+
+ try
+ {
+ IPAddress camIP = System.Net.IPAddress.Parse(IPAddress);
+ _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ IPEndPoint ep = new IPEndPoint(camIP, Port);
+ _socket.Connect(ep);
+ }
+ catch(Exception)
+ {
+ string msg = $"Error connecting to IP address '{IPAddress}:{Port}'.";
+ log.Error(msg);
+ throw ExceptionBuilder.Build(typeof(ConnectionFailedException), Name, "error_connectionFailed", msg);
+ }
+
+ ActivateChannel(ChannelNames.Distance);
+ ActivateChannel(ChannelNames.Point3DImage);
+ ActivateChannel(ChannelNames.Intensity);
+ SelectChannel(ChannelNames.Intensity);
+
+ _updateThread.Start();
+ }
+
+ protected override void DisconnectImpl()
+ {
+ _cancelUpdateThreadSource.Cancel();
+ _updateThread.Join();
+ _socket.Close();
+ _frameAvailable.Reset();
+ }
+
+ protected override void UpdateImpl()
+ {
+ _frameAvailable.WaitOne();
+
+ if (null != _updateThreadError)
+ {
+ Disconnect();
+ if (null != _updateThreadException)
+ {
+ throw new ImageAcquisitionFailedException(_updateThreadError, _updateThreadException);
+ }
+ else
+ {
+ throw new ImageAcquisitionFailedException(_updateThreadError);
+ }
+ }
+
+ _frontJsonData = _backJsonData;
+ }
+
+ protected override CameraImage CalcChannelImpl(string channelName)
+ {
+ switch (channelName)
+ {
+ case ChannelNames.Intensity:
+ return ParseImage(_frontJsonData, _intensityJsonOffset, _intensityJsonSize, 1.0f);
+ case ChannelNames.Distance:
+ return ParseImage(_frontJsonData, _distanceJsonOffset, _distanceJsonSize);
+ case ChannelNames.Point3DImage:
+ return GetScaledDistances(ParseImage(_frontJsonData, _distanceJsonOffset, _distanceJsonSize));
+ }
+
+ log.Error(Name + ": Invalid channelname: " + channelName);
+ return null;
+ }
+
+
+ //TODO: Metrilus.Util should implement the *-operator on FloatCameraImage and Point3fCameraImage in future. Then just replace this method.
+ private Point3fCameraImage GetScaledDistances(FloatCameraImage distances)
+ {
+ Point3fCameraImage coords = new Point3fCameraImage(distances.Width, distances.Height);
+ for(int i = 0; i < coords.Length; i++)
+ {
+ coords[i] = distances[i] * _directions[i];
+ }
+ return coords;
+ }
+
+ private Point3fCameraImage CalcDirections(InverseBrownConradyParams intrinsics, int width, int height)
+ {
+ Point3fCameraImage directions = new Point3fCameraImage(width, height);
+ for (int row = 0; row < height; row++)
+ {
+ float yp = (intrinsics.Cy - row) / intrinsics.Fy;
+ float yp2 = yp * yp;
+
+ for (int col = 0; col < width; col++)
+ {
+ float xp = (intrinsics.Cx - col) / intrinsics.Fx;
+
+ // correct the camera distortion
+ float r2 = xp * xp + yp2;
+ float r4 = r2 * r2;
+ float k = 1 + intrinsics.K1 * r2 + intrinsics.K2 * r4;
+
+ // Undistorted direction vector of the point
+ float x = xp * k;
+ float y = yp * k;
+ float s0Inv = (float)(1 / Math.Sqrt(x * x + y * y + 1)); //z is 1, since x and y are coordinates on normalized image plane.
+
+ directions[row, col] = new Point3f(-x * s0Inv, -y * s0Inv, s0Inv);
+ }
+ }
+ return directions;
+ }
+
+ #endregion
+
+ private void UpdateLoop()
+ {
+ int consecutiveFailCounter = 0;
+ while (!_cancelUpdateThreadSource.Token.IsCancellationRequested)
+ {
+ try
+ {
+ // 0 - CameraModel
+ // 1 - distance Image
+ // 2 - intensity Image
+ SyncCola();
+ uint jsonSize = ReceiveDataSize();
+ _backJsonData = ReceiveJsonString(jsonSize);
+ if(null == _directions)
+ {
+ string json = new string(_backJsonData);
+ var frameData = JsonConvert.DeserializeObject>(json);
+ _imageWidth = frameData[1].Data.Data.Width;
+ _imageHeight = frameData[1].Data.Data.Height;
+ InverseBrownConradyParams intrinsics = ParseIntrinsics(frameData[0]);
+ _directions = CalcDirections(intrinsics, _imageWidth, _imageHeight);
+
+ //Determine the offsets of intensity and distance image, which are stable over time.
+ string needle = "\"data\":\"";
+ int start_first_img = json.IndexOf(needle, 0) + needle.Length;
+ int end_first_img = json.IndexOf("\"", start_first_img);
+ _distanceJsonOffset = start_first_img;
+ _distanceJsonSize = end_first_img - start_first_img;
+ int start_second_img = json.IndexOf(needle, end_first_img) + needle.Length;
+ int end_second_img = json.IndexOf("\"", start_second_img);
+ _intensityJsonOffset = start_second_img;
+ _intensityJsonSize = end_second_img - start_second_img;
+
+ if ("uint16" != frameData[1].Data.Data.ImageType
+ || "uint16" != frameData[2].Data.Data.ImageType)
+ {
+ string format = frameData[1].Data.Data.ImageType != "uint16" ? frameData[1].Data.Data.ImageType : frameData[2].Data.Data.ImageType;
+ string msg = $"{Name}: Frame data has unexpected format: '{format}', expected: 'uint16'";
+ log.Error(msg);
+ throw new ImageAcquisitionFailedException(msg);
+ }
+
+ if ("little" != frameData[1].Data.Data.Pixels.endian
+ || "little" != frameData[2].Data.Data.Pixels.endian)
+ {
+ string endian = frameData[1].Data.Data.Pixels.endian != "little" ? frameData[1].Data.Data.Pixels.endian : frameData[2].Data.Data.Pixels.endian;
+ string msg = $"{Name}: Frame data has unexpected endian: '{endian}', expected: 'little'";
+ log.Error(msg);
+ throw new ImageAcquisitionFailedException(msg);
+ }
+ }
+ _frameAvailable.Set();
+ }
+ catch(Exception e)
+ {
+ consecutiveFailCounter++;
+ if (consecutiveFailCounter > NumFrameRetries)
+ {
+ string msg = $"{Name}: Receive failed more than {NumFrameRetries} times in a row. Shutting down update loop.";
+ log.Error(msg);
+ log.Error(e.Message);
+ _updateThreadError = msg;
+ _updateThreadException = e;
+ _frameAvailable.Set();
+ break;
+ }
+ }
+
+ // reset counter after sucessfull fetch
+ consecutiveFailCounter = 0;
+ }
+ }
+
+ private void SyncCola()
+ {
+ int elements = 0;
+ while(elements < 4)
+ {
+ byte[] buffer = new byte[1];
+ _socket.Receive(buffer, 1, SocketFlags.None);
+
+ if(buffer[0] == 0x02)
+ {
+ elements++;
+ }
+ else
+ {
+ elements = 0;
+ }
+ }
+ }
+
+ private uint ReceiveDataSize()
+ {
+ uint bufferSize = sizeof(uint);
+ byte[] buffer = new byte[bufferSize];
+ _socket.Receive(buffer, (int)bufferSize, SocketFlags.None);
+ Array.Reverse(buffer);
+ return BitConverter.ToUInt32(buffer, 0);
+ }
+
+ private char[] ReceiveJsonString(uint dataSize)
+ {
+ byte[] buffer = new byte[dataSize];
+ uint bytesReceived = 0;
+
+ while(bytesReceived < dataSize)
+ {
+ int received = _socket.Receive(buffer, (int)bytesReceived, (int)(dataSize - bytesReceived), SocketFlags.None, out SocketError error);
+ bytesReceived += (uint)received;
+ }
+ try
+ {
+ return Encoding.UTF8.GetChars(buffer);
+ }
+ catch(Exception e)
+ {
+ string msg = $"{Name}: Invalid UTF-8 byte sequence received: {e.Message}";
+ log.Error(msg);
+ throw new ImageAcquisitionFailedException(msg);
+ }
+ }
+
+ private InverseBrownConradyParams ParseIntrinsics(CameraObject metaObj)
+ {
+ if (null == metaObj.Data.IntrinsicK)
+ {
+ string msg = $"{Name}: Invalid camera meta information received";
+ log.Error(msg);
+ throw new ImageAcquisitionFailedException(msg);
+ }
+
+ return new InverseBrownConradyParams()
+ {
+ Fx = metaObj.Data.IntrinsicK[0][0],
+ Fy = metaObj.Data.IntrinsicK[1][1],
+ Cx = metaObj.Data.IntrinsicK[0][2],
+ Cy = metaObj.Data.IntrinsicK[1][2],
+ K1 = metaObj.Data.SensorToWorldDistortion[0][0],
+ K2 = metaObj.Data.SensorToWorldDistortion[1][0],
+ P1 = metaObj.Data.SensorToWorldDistortion[2][0],
+ P2 = metaObj.Data.SensorToWorldDistortion[3][0],
+ K3 = metaObj.Data.SensorToWorldDistortion[4][0]
+ };
+ }
+
+ private unsafe FloatCameraImage ParseImage(char[] base64Data, int offset, int length, float scaleFactor = 1000.0f)
+ {
+ byte[] raw = Convert.FromBase64CharArray(base64Data, offset, length);
+
+ FloatCameraImage image = new FloatCameraImage(_imageWidth, _imageHeight);
+
+ fixed (byte* rawData = raw)
+ {
+ ushort* ushortData = (ushort*)rawData;
+ if (scaleFactor != 1.0f)
+ {
+ for (int i = 0; i < image.Length; i++)
+ {
+ image[i] = *ushortData / scaleFactor;
+ ushortData++;
+ }
+ }
+ else
+ {
+ for (int i = 0; i < image.Length; i++)
+ {
+ image[i] = *ushortData;
+ ushortData++;
+ }
+ }
+ }
+
+ return image;
+ }
+ }
+}
diff --git a/BetaCameras/Sick.VisionaryT/VisionaryT.cs b/BetaCameras/Sick.VisionaryT/VisionaryT.cs
index c458cd7f..31e56cfe 100644
--- a/BetaCameras/Sick.VisionaryT/VisionaryT.cs
+++ b/BetaCameras/Sick.VisionaryT/VisionaryT.cs
@@ -26,7 +26,7 @@ public class VisionaryT : Camera
// ipAddress to connect to
private string ipAddress;
// device handle
- private Device device;
+ private Device _device;
private Control _control;
// image data contains information about the current frame e.g. width and height
@@ -155,7 +155,7 @@ public VisionaryT()
: base()
{
ipAddress = "";
- device = null;
+ _device = null;
_frontFrameData = null;
_backFrameData = null;
_updateThread = null;
@@ -167,7 +167,8 @@ public VisionaryT()
#region MetriCam2 Camera Interface
#region MetriCam2 Camera Interface Properties
/// The camera's name.
- public new string Name { get => "Visionary-T"; }
+ public override string Name { get => "Visionary-T"; }
+ public override string Vendor { get => "Sick"; }
#endregion
#region MetriCam2 Camera Interface Methods
@@ -202,7 +203,7 @@ protected override void ConnectImpl()
log.Error(msg);
throw ExceptionBuilder.Build(typeof(ConnectionFailedException), Name, "error_connectionFailed", msg);
}
- device = new Device(ipAddress, this, log);
+ _device = new Device(ipAddress, this, log);
_control = new Control(log, ipAddress);
_control.StartStream();
@@ -227,8 +228,8 @@ protected override void DisconnectImpl()
_updateThread = null;
_control.Close();
_control = null;
- device.Disconnect();
- device = null;
+ _device.Disconnect();
+ _device = null;
}
///
@@ -292,7 +293,7 @@ private void UpdateLoop()
{
lock (_backLock)
{
- byte[] imageBuffer = device.GetFrameData();
+ byte[] imageBuffer = _device.GetFrameData();
_backFrameData = new FrameData(imageBuffer, this, log);
_frameAvailable.Set();
}
diff --git a/MetriCam2_SDK.sln b/MetriCam2_SDK.sln
index 22a2a791..2912e15c 100644
--- a/MetriCam2_SDK.sln
+++ b/MetriCam2_SDK.sln
@@ -83,6 +83,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BaslerACE", "BetaCameras\Ba
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pico", "BetaCameras\Pico\Pico.csproj", "{1FAD1F90-D37E-40CA-BBF0-6A33E82F8812}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sick.VisionaryT.Pro", "BetaCameras\Sick.VisionaryT.Pro\Sick.VisionaryT.Pro.csproj", "{D01829D2-B553-4C4B-B392-2437E6A130B5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -555,6 +557,22 @@ Global
{1FAD1F90-D37E-40CA-BBF0-6A33E82F8812}.ReleaseStrongName|Any CPU.ActiveCfg = Release|Any CPU
{1FAD1F90-D37E-40CA-BBF0-6A33E82F8812}.ReleaseStrongName|x64.ActiveCfg = Release|Any CPU
{1FAD1F90-D37E-40CA-BBF0-6A33E82F8812}.ReleaseStrongName|x86.ActiveCfg = Release|Any CPU
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.Debug|x64.ActiveCfg = Debug|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.Debug|x64.Build.0 = Debug|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.Debug|x86.ActiveCfg = Debug|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.DebugStrongName|Any CPU.ActiveCfg = Release|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.DebugStrongName|Any CPU.Build.0 = Release|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.DebugStrongName|x64.ActiveCfg = Debug|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.DebugStrongName|x86.ActiveCfg = DebugStrongName|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.Release|Any CPU.ActiveCfg = Release|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.Release|x64.ActiveCfg = Release|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.Release|x64.Build.0 = Release|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.Release|x86.ActiveCfg = Release|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.ReleaseStrongName|Any CPU.ActiveCfg = Release|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.ReleaseStrongName|Any CPU.Build.0 = Release|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.ReleaseStrongName|x64.ActiveCfg = Release|x64
+ {D01829D2-B553-4C4B-B392-2437E6A130B5}.ReleaseStrongName|x86.ActiveCfg = ReleaseStrongName|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -583,6 +601,7 @@ Global
{9CBCE2AB-4E19-4344-B3CF-67D07CC9C8FC} = {4817E415-1337-4CA1-BF30-23D3EA0F806B}
{474D94F4-857B-4199-97AF-C600AED44406} = {4817E415-1337-4CA1-BF30-23D3EA0F806B}
{1FAD1F90-D37E-40CA-BBF0-6A33E82F8812} = {4817E415-1337-4CA1-BF30-23D3EA0F806B}
+ {D01829D2-B553-4C4B-B392-2437E6A130B5} = {4817E415-1337-4CA1-BF30-23D3EA0F806B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E4CD8F0D-A50B-44DC-80D3-0C789213BF2B}
diff --git a/Samples/MinimalSample/MinimalSample.csproj b/Samples/MinimalSample/MinimalSample.csproj
index a97470d3..41b63f3c 100644
--- a/Samples/MinimalSample/MinimalSample.csproj
+++ b/Samples/MinimalSample/MinimalSample.csproj
@@ -101,24 +101,6 @@
-
-
- {c82202f8-55db-4511-b006-c88ff3e4427e}
- OrbbecOpenNI
-
-
- {de18d143-c624-4941-b8a1-0f91262d3350}
- Sick.VisionaryT
-
-
- {01c2fb4d-1f35-4855-9b53-0480519387c5}
- WebCam
-
-
- {342f049e-668b-4351-b21d-75e4bef5a1e4}
- MetriCam2
-
-
.licenseheader
@@ -132,6 +114,16 @@
false
+
+
+ {c82202f8-55db-4511-b006-c88ff3e4427e}
+ OrbbecOpenNI
+
+
+ {342f049e-668b-4351-b21d-75e4bef5a1e4}
+ MetriCam2
+
+
-
+
\ No newline at end of file
diff --git a/Scripts/Jenkinsfile.groovy b/Scripts/Jenkinsfile.groovy
index 542892cd..99f5dfeb 100644
--- a/Scripts/Jenkinsfile.groovy
+++ b/Scripts/Jenkinsfile.groovy
@@ -9,7 +9,7 @@ pipeline {
def V_MINOR = "${versionInfo['VERSION_MINOR']}"
def V_BUILD = "${versionInfo['VERSION_BUILD']}"
- def dllsToDeployX64 = 'CookComputing.XmlRpcV2 MetriCam2.Cameras.BaslerACE MetriCam2.Cameras.BaslerToF MetriCam2.Cameras.ifm MetriCam2.Cameras.Kinect2 MetriCam2.Cameras.MatrixVision MetriCam2.Cameras.OrbbecOpenNI MetriCam2.Cameras.Sick.TiM561 MetriCam2.Cameras.Sick.VisionaryT MetriCam2.Cameras.SVS MetriCam2.Cameras.TIVoxel MetriCam2.Cameras.UEye MetriCam2.Cameras.WebCam MetriCam2.Cameras.Pico'
+ def dllsToDeployX64 = 'CookComputing.XmlRpcV2 MetriCam2.Cameras.BaslerACE MetriCam2.Cameras.BaslerToF MetriCam2.Cameras.ifm MetriCam2.Cameras.Kinect2 MetriCam2.Cameras.MatrixVision MetriCam2.Cameras.OrbbecOpenNI MetriCam2.Cameras.Sick.TiM561 MetriCam2.Cameras.Sick.VisionaryT MetriCam2.Cameras.Sick.VisionaryT.Pro MetriCam2.Cameras.SVS MetriCam2.Cameras.TIVoxel MetriCam2.Cameras.UEye MetriCam2.Cameras.WebCam MetriCam2.Cameras.Pico'
def dllsToDeployAnyCPU = 'Intel.RealSense log4net MathNet.Numerics MetriCam2 MetriCam2.Cameras.RealSense2 MetriCam2.Controls Metrilus.Util Newtonsoft.Json'
def dllsToDeployNetStandard = 'MetriCam2 MetriCam2.Cameras.RealSense2 Metrilus.Util'
def dllsToDeployX64StrongName = 'MetriCam2.Cameras.Kinect2 MetriCam2.Cameras.OrbbecOpenNI MetriCam2.Cameras.Sick.VisionaryT'