qualisys / qualisys_dotnet_sdk

C# (.NET) implementation of the real-time protocol for Qualisys Track Manager
MIT License
8 stars 5 forks source link

ruining the example #1

Closed RSChegani closed 8 years ago

RSChegani commented 8 years ago

Hi,

I'm trying to run the example, but so far no luck. in line 21, when it enters IP address, should it be the IP address that camera's are connected to? by the way, why there is no line in the program that connects it to QTM, something like rtProtocol.conncet(); any idea can be useful

Thanks

bdazl commented 8 years ago

Hi,

The RT-protocol connects to QTM, i.e. the host computer of the cameras, and usually QTM is run on the localhost (127.0.0.1).

There is a connect command inside the method HandleStreaming in the Example class (called by line 21 of file Program.cs, in the example). This is located a bit further down.

Regards, Jacob - Software developer at Qualisys.

bdazl commented 8 years ago

I might write a little tutorial later that might clear things up. Stay tuned!

RSChegani commented 8 years ago

Hi,

Thank you for your explnation. I have QTM and C# runnibg at the same pc, but it did not work till I changed connect command's input. I am able to connect to QTM, but I don't know how to get 3D data from it. I'm sure a little tutorial will be great

Thank you Rana

On Sunday, May 15, 2016, Jacob Peyron notifications@github.com wrote:

I might write a little tutorial later that might clear things up. Stay tuned!

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub< https://ci4.googleusercontent.com/proxy/nkQLgUUNGaA_MNL8fIu0XY3anClNFQw6Zv_byj5-BQjczwNf-Lb_aJQmBstbuw97pfaY2ph0axmQshHkssMymH5kvNzNt717yKnqFLYesIBcIw1Nb3shZkEW0kcWN1L5pO1k7pN9LpJtXVLk_oNwkZc3XHqcyQ=s0-d-e1-ft#https://github.com/notifications/beacon/ASdUfaZido8ul5QmHefrdc8ScF3OCrtqks5qCAvlgaJpZM4Ieem1.gif

Ra'na Sadeghi Chegani, B.Sc.,
M.A.Sc. Studies at MENRVA Research Laboratory
Simon Fraser University, School of Engineering Science,
8888 University Dr., Burnaby, BC, V5A 1S6, Canada
URL: http://menrva.ensc.sfu.ca; Tel.: (001)-778-681-3560
<callto:(001)-778-681-3560>
RSChegani commented 8 years ago

Dear Jacob,

I'm still struggling with this example, and I cannot make it work. I run QTM and at the same time I run the example. after connecting, it starts to get the packet data. to make sure that I'm reviving the right packet I added, Console.WriteLine("PacketData") before line 93. after printing this line in console it does not print anything else. to make sure that it receives 6Dof data I added Console.WriteLine(sixDofData.Count) before line 97. it prints 0. so I assumed that I'm not recording 6DoF data, which I am. so I tried to see is there any other data that my program is sending, and I added var threeDofDataResidual = rtProtocol.GetRTPacket().Get3DMarkerResidualData(); var threeDofData = rtProtocol.GetRTPacket().Get3DMarkerData(); var twoDofData = rtProtocol.GetRTPacket().Get2DMarkerData();

            if (threeDofData != null)
            {
                Console.WriteLine(threeDofData);
            }

            if(twoDofData != null)
            {
                Console.WriteLine(twoDofData);
            }
            if (threeDofDataResidual != null)
            {
                Console.WriteLine(threeDofDataResidual);

            }

all of them result in printing 0 on console. can you help me to solve this problem?

thanks, Rana

bdazl commented 8 years ago

Hi again Rana, Are you in preview/measure when you're doing this or do you want to fetch data from an already recorded measurement? Regardless of how you want your data to be streamed, try another variant. For example, if you've been trying regular RT/preview, try playing a file for RT (In the QTM menu: Play->Play with RT output).

The 2D and 3D data is not present since the example program only asks for 6DOF bodies (you have to explicitly tell the protocol/QTM what data you're interested in; see line 81 StreamAllFrames()).

Hope it helps, Jacob

RSChegani commented 8 years ago

I 'm posting the whole program here, which is not giving me any result // Realtime SDK Example for Qualisys Track Manager. Copyright 2016 Qualisys AB // using System; using System.Collections.Generic; using System.Threading; using QTMRealTimeSDK; using QTMRealTimeSDK.Data;

namespace RTSDKExample { class Program { static void Main(string[] args) { Example example = new Example(); example.DiscoverQTMServers(4547); Console.WriteLine("Press key to continue"); Console.ReadKey(); while (true) { example.HandleStreaming("127.0.0.1"); if (Console.KeyAvailable) { if (Console.ReadKey(false).Key == ConsoleKey.Escape) break; } } } }

class Example
{
    RTProtocol rtProtocol = new RTProtocol();

    public void DiscoverQTMServers(ushort discoveryPort)
    {
        if (rtProtocol.DiscoverRTServers(discoveryPort))
        {
            var discoveryResponses = rtProtocol.DiscoveryResponses;
            foreach (var discoveryResponse in discoveryResponses)
            {
                Console.WriteLine("Host:{0,20}\tIP Adress:{1,15}\tInfo Text:{2,20}\tCamera count:{3,3}", discoveryResponse.HostName, discoveryResponse.IpAddress, discoveryResponse.InfoText, discoveryResponse.CameraCount);
            }
        }
    }

    ~Example()
    {
        if (rtProtocol.IsConnected())
        {
            rtProtocol.StreamFramesStop();
            rtProtocol.Disconnect();
        }
    }

    public void HandleStreaming(string ipAddress)
    {
        // Check if connection to QTM is possible
        if (!rtProtocol.IsConnected())
        {
            if (!rtProtocol.Connect("192.168.0.1", 0, 1, 10))
            {
                Console.WriteLine("QTM: Trying to connect");
                Thread.Sleep(1000);
                return;
            }
            Console.WriteLine("QTM: Connected");
        }

        // Check for available 3DOF with residual data in the stream
        if (rtProtocol.Settings3D == null)
        {
            if (!rtProtocol.Get3Dsettings())
            {
                Console.WriteLine("QTM: Trying to get 3DOF settings");
                Thread.Sleep(500);
                return;
            }
            Console.WriteLine("QTM: 3DOF data available");

            rtProtocol.StreamAllFrames(QTMRealTimeSDK.Data.ComponentType.Component3dNoLabelsResidual);
            Console.WriteLine("QTM: Starting to stream 3DOF data");
            Thread.Sleep(500);
        }

        // Get RTPacket from stream
        PacketType packetType;
        rtProtocol.ReceiveRTPacket(out packetType, false);

        // Handle data packet
        if (packetType == PacketType.PacketData)
        {
            var threeDofData = rtProtocol.GetRTPacket().Get3DMarkerResidualData();
            if (threeDofData != null)
            {
                Console.WriteLine(rtProtocol.GetRTPacket().Get3DMarkerResidualData().Count);
                // Print out the available 6DOF data.
                for (int body = 0; body < rtProtocol.GetRTPacket().Get3DMarkerResidualData().Count; body++)
                {
                    var threeDofBody = threeDofData[body];
                 //   var bodySetting = rtProtocol.Settings3D.;
                    Console.WriteLine("Frame:{0:D5} X:{2,7:F1} Y:{3,7:F1} Z:{4,7:F1} Residual:{8,7:F1}",
                        rtProtocol.GetRTPacket().Frame,
                        threeDofBody.Position.X, threeDofBody.Position.Y, threeDofBody.Position.Z,
                        threeDofBody.Residual);
                }
            }
        }

        // Handle event packet
        if (packetType == PacketType.PacketEvent)
        {
            // If an event comes from QTM then print it out
            var qtmEvent = rtProtocol.GetRTPacket().GetEvent();
            Console.WriteLine("{0}", qtmEvent);
        }
    }
}

}

qualisys commented 8 years ago

Hi,

In the Program::Main method the ip address set to "127.0.0.1" (localhost), but in the Example::HandleStreaming the ipAddress variable isn't used, but another ip address "192.168.0.1" is used instead. I would suggest to change it to if (!rtProtocol.Connect(ipAddress, 0, 1, 10)) instead and use the call to HandleStreaming to set which ip address to use.

The ip address should be the ip address of the computer that is running QTM. QTM must either be running realtime or capturing (File menu->New or Capture menu->Capture) or playing realtime from recorded file (Open a .qtm file then do Play menu->Play with realtime output).

If you are running the example and QTM on the same machine use the ip address "127.0.0.1" (localhost).

Best regards, Morgan

RSChegani commented 8 years ago

Thank you Morgan for your suggestions, I used your suggestions and I'm still not able to get any output. to see if it is actually reading the markers or not, I change: rtProtocol.StreamAllFrames(QTMRealTimeSDK.Data.ComponentType.Component3dNoLabelsResidual);

to rtProtocol.StreamAllFrames(QTMRealTimeSDK.Data.ComponentType.ComponentAll);

and add: if (packetType == PacketType.PacketData) {

            Console.WriteLine(rtProtocol.GetRTPacket().Get3DMarkerData().Count);
            Console.WriteLine(rtProtocol.GetRTPacket().Get3DMarkerResidualData().Count);
       }

it prints zeros, it looks like it is not able to read markers at all. I run the program while qtm is running and capturing 3 markers. and if I run RTClientExample.exe from c++ sdk, it reads all 3 markers and give out their locations. I really appreciate it If you can help me to find out the problem, since it has been holding back my project

p.s : here is my final program, the only result that I get is 0:

// Realtime SDK Example for Qualisys Track Manager. Copyright 2016 Qualisys AB // using System; using System.Collections.Generic; using System.Threading; using QTMRealTimeSDK; using QTMRealTimeSDK.Data;

namespace RTSDKExample { class Program { static void Main(string[] args) { Example example = new Example(); example.DiscoverQTMServers(4547); Console.WriteLine("Press key to continue"); Console.ReadKey(); while (true) { example.HandleStreaming("127.0.0.1"); if (Console.KeyAvailable) { if (Console.ReadKey(false).Key == ConsoleKey.Escape) break; } } } }

class Example
{
    RTProtocol rtProtocol = new RTProtocol();

    public void DiscoverQTMServers(ushort discoveryPort)
    {
        if (rtProtocol.DiscoverRTServers(discoveryPort))
        {
            var discoveryResponses = rtProtocol.DiscoveryResponses;
            foreach (var discoveryResponse in discoveryResponses)
            {
                Console.WriteLine("Host:{0,20}\tIP Adress:{1,15}\tInfo Text:{2,20}\tCamera count:{3,3}", discoveryResponse.HostName, discoveryResponse.IpAddress, discoveryResponse.InfoText, discoveryResponse.CameraCount);
            }
        }
    }

    ~Example()
    {
        if (rtProtocol.IsConnected())
        {
            rtProtocol.StreamFramesStop();
            rtProtocol.Disconnect();
        }
    }

    public void HandleStreaming(string ipAddress)
    {
        // Check if connection to QTM is possible
        if (!rtProtocol.IsConnected())
        {
            if (!rtProtocol.Connect(ipAddress))
            {
                Console.WriteLine("QTM: Trying to connect");
                Thread.Sleep(1000);
                return;
            }
            Console.WriteLine("QTM: Connected");
        }

        // Check for available 3D data in the stream
        if (rtProtocol.Settings3D == null)
        {
            if (!rtProtocol.Get3Dsettings())
            {
                Console.WriteLine("QTM: Trying to get 3D settings");
                Thread.Sleep(500);
                return;
            }
            Console.WriteLine("QTM: 3D data available");

            rtProtocol.StreamAllFrames(QTMRealTimeSDK.Data.ComponentType.Component3dNoLabelsResidual);
            Console.WriteLine("QTM: Starting to stream 3D data");
            Thread.Sleep(500);
        }

        // Get RTPacket from stream
        PacketType packetType;
        rtProtocol.ReceiveRTPacket(out packetType, false);

        // Handle data packet
        if (packetType == PacketType.PacketData)
        {

            Console.WriteLine(rtProtocol.GetRTPacket().Get3DMarkerResidualData().Count);

            var threeDData = rtProtocol.GetRTPacket().Get3DMarkerResidualData();
            if (threeDData != null)
            {
                // Print out the available 3D data.
                for (int marker = 0; marker < threeDData.Count; marker++)
                {
                    var threeDmarker = threeDData[marker];
                    var markerSetting = rtProtocol.Settings3D.bones[marker];
                    Console.WriteLine("Frame:{0:D5} X:{2,7:F1} Y:{3,7:F1} Z:{4,7:F1} Residual:{8,7:F1}",
                        rtProtocol.GetRTPacket().Frame,
                        threeDmarker.Position.X, threeDmarker.Position.Y, threeDmarker.Position.Z,
                        threeDmarker.Residual);
                }
            }
        }

        // Handle event packet
        if (packetType == PacketType.PacketEvent)
        {
            // If an event comes from QTM then print it out
            var qtmEvent = rtProtocol.GetRTPacket().GetEvent();
            Console.WriteLine("{0}", qtmEvent);
        }
    }
}

}

qualisys commented 8 years ago

Hi again,

I have fixed your code so that it works. The issue you had problem with is that you wanted streaming of Component3dNoLabelsResidual data and then tried to Get3DMarkerResidualData.

You should use Component3dResidual to get data using Get3DMarkerResidualData. That will take the 3d marker data from the labeled trajectory list.

Below is a working 3D with residuals example:

// Realtime SDK Example for Qualisys Track Manager. Copyright 2016 Qualisys AB
//
using System;
using System.Collections.Generic;
using System.Threading;
using QTMRealTimeSDK;
using QTMRealTimeSDK.Data;

namespace RTSDKExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Example example = new Example();
            example.DiscoverQTMServers(4547);
            Console.WriteLine("Press key to continue");
            Console.ReadKey();
            while (true)
            {
                example.HandleStreaming("127.0.0.1");
                if (Console.KeyAvailable)
                {
                    if (Console.ReadKey(false).Key == ConsoleKey.Escape)
                        break;
                }
            }
        }
    }
    class Example
    {
        RTProtocol rtProtocol = new RTProtocol();

        public void DiscoverQTMServers(ushort discoveryPort)
        {
            if (rtProtocol.DiscoverRTServers(discoveryPort))
            {
                var discoveryResponses = rtProtocol.DiscoveryResponses;
                foreach (var discoveryResponse in discoveryResponses)
                {
                    Console.WriteLine("Host:{0,20}\tIP Adress:{1,15}\tInfo Text:{2,20}\tCamera count:{3,3}", discoveryResponse.HostName, discoveryResponse.IpAddress, discoveryResponse.InfoText, discoveryResponse.CameraCount);
                }
            }
        }

        ~Example()
        {
            if (rtProtocol.IsConnected())
            {
                rtProtocol.StreamFramesStop();
                rtProtocol.Disconnect();
            }
        }

        public void HandleStreaming(string ipAddress)
        {
            // Check if connection to QTM is possible
            if (!rtProtocol.IsConnected())
            {
                if (!rtProtocol.Connect(ipAddress, 0, 1, 10))
                {
                    Console.WriteLine("QTM: Trying to connect");
                    Thread.Sleep(1000);
                    return;
                }
                Console.WriteLine("QTM: Connected");
            }

            // Check for available 3DOF with residual data in the stream
            if (rtProtocol.Settings3D == null)
            {
                if (!rtProtocol.Get3Dsettings())
                {
                    Console.WriteLine("QTM: Trying to get 3DOF settings");
                    Thread.Sleep(500);
                    return;
                }
                Console.WriteLine("QTM: 3DOF data available");

                rtProtocol.StreamAllFrames(QTMRealTimeSDK.Data.ComponentType.Component3dResidual);
                Console.WriteLine("QTM: Starting to stream 3DOF data");
                Thread.Sleep(500);
            }

            // Get RTPacket from stream
            PacketType packetType;
            rtProtocol.ReceiveRTPacket(out packetType, false);

            // Handle data packet
            if (packetType == PacketType.PacketData)
            {
                var threeDofData = rtProtocol.GetRTPacket().Get3DMarkerResidualData();
                if (threeDofData != null)
                {
                    Console.WriteLine(rtProtocol.GetRTPacket().Get3DMarkerResidualData().Count);
                    for (int body = 0; body < rtProtocol.GetRTPacket().Get3DMarkerResidualData().Count; body++)
                    {
                        var threeDofBody = threeDofData[body];
                        Console.WriteLine("Frame:{0:D5} X:{1,7:F1} Y:{2,7:F1} Z:{3,7:F1} Residual:{4,7:F1}",
                            rtProtocol.GetRTPacket().Frame,
                            threeDofBody.Position.X, threeDofBody.Position.Y, threeDofBody.Position.Z,
                            threeDofBody.Residual);
                    }
                }
            }

            // Handle event packet
            if (packetType == PacketType.PacketEvent)
            {
                // If an event comes from QTM then print it out
                var qtmEvent = rtProtocol.GetRTPacket().GetEvent();
                Console.WriteLine("{0}", qtmEvent);
            }
        }
    }
}

Best regards, Morgan

RSChegani commented 8 years ago

Hi Morgan,

Thank you so much for your time, the program that you provide is working great. But the reason that I was using Component3dNoLabelsResidual data is that I need not labeled markers' data be streamed. some thing like 3D No label with residuals in c++ program. Does this sdk has any thing similar? the reason that I'm using it is that I have another device which is connected to pc with a serial port and I want to collect data from mocap and my device at the exact same time, and I was not able to understand C++ program as it is a complete program. if you can help me to get 3D No label data, I really appreciate it.

Regards Rana

qualisys commented 8 years ago

Hi,

You can use the different Component types to specify what you want.

You want to use the combination of Component3dNoLabelsResidual and the appropriate method RTPacket.Get3DMarkerNoLabelsResidualData() to stream and read unidentified 3d marker data with residuals.

I have improved the code a bit and added more comments to help out with this kind of questions. Here is the current updated code taken from RTPacket.cs where all the different Component types and their appropriate data get methods are shown. So I would recommend you to pull/clone the latest code so you get the updated method names etc.

    /// <summary>Type of component streamed</summary>
    public enum ComponentType
    {
        // Labeled 3d markers (Get3DMarkerData)
        Component3d = 1,
        // Unidentified 3d markers (Get3DMarkerNoLabelsData)
        Component3dNoLabels,
        // Analog data (GetAnalogData)
        ComponentAnalog,
        // Force data (GetForceData)
        ComponentForce,
        // 6D data - position and rotation matrix (Get6DOFData)
        Component6d,
        // 6D data - position and Euler angles (Get6DOFEulerData)
        Component6dEuler,
        // 2D marker data (Get2DMarkerData)
        Component2d,
        // Linearized 2D marker data (Get2DLinearizedMarkerDAta)
        Component2dLinearized,
        // Labeled 3d markers with residual (Get3DMarkerResidualData)
        Component3dResidual,
        // Unidentified 3d markers with residual (Get3DMarkerNoLabelsResidualData)
        Component3dNoLabelsResidual,
        // 6D data - position and rotation matrix with residuals with residual (Get6DOFResidualData)
        Component6dResidual,
        // 6D data - position and Euler angles with residual (Get6DOFEulerResidualData)
        Component6dEulerResidual,
        // Analog data from available analog devices. Only one sample per channel and camera frame. The latest sample is used if more than one sample is available. (GetAnalogSingleData)
        ComponentAnalogSingle,
        // Image frame from a specific camera. Image size and format is set with the XML settings, see Image settings. (GetImageData)
        ComponentImage,
        // Force data from available force plates. Only one sample per plate and camera frame. The latest sample is used if more than one sample is available. (GetForceSingleData)
        ComponentForceSingle,
        // Gaze vector data from eye tracker (GetGazeVectorData)
        ComponentGazeVector,
        // Nothing
        ComponentNone,
        // Stream everything
        ComponentAll
    }

Best regards, Morgan

RSChegani commented 8 years ago

Thank you so much Morgan, it's working great