Announcement

Collapse
No announcement yet.

Help with integrating OPTOTRAK 3020 and Matlab

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Help with integrating OPTOTRAK 3020 and Matlab

    Hello all! This is my first post on here. I was hoping someone more experienced with programming, and such, might be able to help me with an issue I am having. I am not familiar with the C language, and I am just mildly seasoned in Matlab. I am trying to use the optotoolbox of functions created for Matlab to write incoming marker data to a variable, that is, rather than using the fprintf function to write to a text file. If anybody here might be able to help with this, well, I would greatly appreciate it.

    Justin Fine

  • #2
    Re: Help with integrating OPTOTRAK 3020 and Matlab

    If all you're trying to do is save data out in Matlab format, then it's just a matter of assigning the output of the function that is reading the marker to a Matlab variable and saving it out using the 'save' function. I don't know the Optotrak tool box per se, but this is a fairly standard Matlab operation.

    Comment


    • #3
      Re: Help with integrating OPTOTRAK 3020 and Matlab

      Hi Justin,

      Can you post a few lines of the relevant code, then I'm sure that someone will be able to help you.

      Jason

      Comment


      • #4
        Re: Help with integrating OPTOTRAK 3020 and Matlab

        Here is the portion of the code that is giving me trouble. I am trying to write to the variable, A, matlab is only writing the last sampled value repeatedly instead of appending each sample to the variable. Any help would be appreciated.

        %Loop around spooling data to file and displaying realtime 3d data.
        SpoolComplete=0;
        while(~SpoolComplete)
        %Write data if there is any to write.
        [RealtimeDataReady,SpoolComplete,SpoolStatus,Frames Buffered]=optotrak('DataBufferWriteData');

        %Display realtime if there is any to display.
        if(RealtimeDataReady)
        %Receive the 3D data.
        data=optotrak('DataReceiveLatest3D',coll.NumMarker s);
        for MarkerCnt = 1:coll.NumMarkers
        for sampleIndex = 1:samples
        A(1:sampleIndex,1) = data.Markers{MarkerCnt}(1);
        A(1:sampleIndex,2) = data.Markers{MarkerCnt}(2);
        A(1:sampleIndex,3) = data.Markers{MarkerCnt}(3);
        end
        end
        end
        %Request a new frame of realtime 3D data.
        optotrak('RequestLatest3D')
        RealtimeDataReady = 0;
        end

        Comment


        • #5
          Re: Help with integrating OPTOTRAK 3020 and Matlab

          Hi Justin,

          If you just want to save to a variable, then you don't need to call "DataBufferWriteData"

          I think you want to do something like this (where samples is the number of samples you want to collect) [not tested]:

          for sampleIndex=1:samples
          data=optotrak('DataReceiveLatest3D',coll.NumMarker s);
          for MarkerCnt=1:coll.NumMarkers
          A(sampleIndex,1) = data.Markers{MarkerCnt}(1);
          A(sampleIndex,2) = data.Markers{MarkerCnt}(2);
          A(sampleIndex,3) = data.Markers{MarkerCnt}(3);
          end
          end

          Note that every time in the outer loop, you need to call "DataReceiveLatest3D" to get a new piece of data.
          Also, if you write A(1:sampleindex,1) then you overwrite all the data with the latest sample, whereas
          A(sampleIndex,1) will only set the last value (as I assume you actually want).

          Jason

          Every time you want a new sample, you need to make a call to DataReceiveLatest3D

          Comment


          • #6
            Re: Help with integrating OPTOTRAK 3020 and Matlab

            Edited to avoid confusion with Jason's message ... written while I was writing mine .... :-)

            Firstly, 'samples' has no defined value in Justin's code snippet.
            One of the first steps in troubleshooting should be to check the values of all variables to see if they makes sense. I assume that the number of samples returned from the optotrak('DataReceiveLatest3D') function can vary ? You will need to test for that.
            Secondly, 'for' loops are rarely the best way to do things in Matlab, esp for real-time code. Look up 'vectorization'. All the marker data should probably be able to be dumped into A in one operation, without one if not both of the 'for' loops. Also '1:sampleIndex' looks wrong (redundant) for the for loop but could be on the right track in a vectorized version.
            Good luck
            Tim
            Last edited by Tim Wrigley; June 14, 2011, 09:44 AM.

            Comment


            • #7
              Re: Help with integrating OPTOTRAK 3020 and Matlab

              Hi Justin,

              The function DataBufferWriteData is a non-blocking (does not prevent code execution until all the data is collected) function for writing data to file, while DataReceiveLatest3D is for capturing a single frame of data. So Jason is correct in stating that the sample index should be incremented for each call to DataReceiveLatest3D. The toolbox you are using is simply a wrapper around the NDI Optotrak API and has no vectorization, to my knowledge.

              In short, your problem is the result of precisely the problem Jason pointed out. You were over-writing the first frame of data with each new frame of data. However, I don't think that you will need to use a for-loop to increment sampleIndex, since the while(~SpoolComplete)-loop will continue to iterate through your code until all the requested data is spooled to disk. You just need to initialize sampleIndex to 0 before the while-loop and increment it at the end of the code within the while-loop. I also noticed, you will probably need to add a MarketCnt index to A or you will only end up with the last marker's data (it having been over-written by each marker's data as it goes through that MarkerCnt for-loop). I would also recommend pre-allocating A before this code runs to avoid memory fragmentation. I haven't tested any of the code below, its just to illustrate my comments.

              A = zeros(samples, coll.NumMarkers, 3); % Pre-allocate A to avoid memory fragmentation
              SpoolComplete = 0;
              sampleIndex = 0;

              %Loop around spooling data to file and displaying realtime 3d data.
              while(~SpoolComplete)
              %Write data if there is any to write.
              [RealtimeDataReady,SpoolComplete,SpoolStatus,Frames Buffered]=optotrak('DataBufferWriteData');

              %Display realtime if there is any to display.
              if(RealtimeDataReady)
              %Receive the 3D data.
              data=optotrak('DataReceiveLatest3D',coll.NumMarker s);
              for MarkerCnt = 1:coll.NumMarkers
              A(sampleIndex, MarkerCnt, 1) = data.Markers{MarkerCnt}(1);
              A(sampleIndex, MarkerCnt, 2) = data.Markers{MarkerCnt}(2);
              A(sampleIndex, MarkerCnt, 3) = data.Markers{MarkerCnt}(3);
              end
              end
              sampleIndex = sampleIndex + 1;
              %Request a new frame of realtime 3D data.
              optotrak('RequestLatest3D')
              RealtimeDataReady = 0;
              end

              Comment

              Working...
              X