| Index: webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc
|
| diff --git a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc b/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc
|
| deleted file mode 100644
|
| index e81813653bbc4f80c1fbf4cf323acd2ae66748f0..0000000000000000000000000000000000000000
|
| --- a/webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.cc
|
| +++ /dev/null
|
| @@ -1,1058 +0,0 @@
|
| -/*
|
| - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
| - *
|
| - * Use of this source code is governed by a BSD-style license
|
| - * that can be found in the LICENSE file in the root of the source
|
| - * tree. An additional intellectual property rights grant can be found
|
| - * in the file PATENTS. All contributing project authors may
|
| - * be found in the AUTHORS file in the root of the source tree.
|
| - */
|
| -
|
| -#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h"
|
| -
|
| -#include <math.h>
|
| -#include <stdio.h>
|
| -
|
| -#include <algorithm>
|
| -#include <sstream>
|
| -
|
| -#ifdef MATLAB
|
| -#include "engine.h" // NOLINT(build/include)
|
| -#endif
|
| -
|
| -#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
|
| -#include "webrtc/system_wrappers/include/event_wrapper.h"
|
| -#include "webrtc/system_wrappers/include/tick_util.h"
|
| -
|
| -using webrtc::CriticalSectionScoped;
|
| -using webrtc::CriticalSectionWrapper;
|
| -using webrtc::EventWrapper;
|
| -using webrtc::TickTime;
|
| -
|
| -#ifdef MATLAB
|
| -MatlabEngine eng;
|
| -
|
| -MatlabLine::MatlabLine(int maxLen /*= -1*/, const char *plotAttrib /*= NULL*/, const char *name /*= NULL*/)
|
| -:
|
| -_xArray(NULL),
|
| -_yArray(NULL),
|
| -_maxLen(maxLen),
|
| -_plotAttribute(),
|
| -_name()
|
| -{
|
| - if (_maxLen > 0)
|
| - {
|
| - _xArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL);
|
| - _yArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL);
|
| - }
|
| -
|
| - if (plotAttrib)
|
| - {
|
| - _plotAttribute = plotAttrib;
|
| - }
|
| -
|
| - if (name)
|
| - {
|
| - _name = name;
|
| - }
|
| -}
|
| -
|
| -MatlabLine::~MatlabLine()
|
| -{
|
| - if (_xArray != NULL)
|
| - {
|
| - mxDestroyArray(_xArray);
|
| - }
|
| - if (_yArray != NULL)
|
| - {
|
| - mxDestroyArray(_yArray);
|
| - }
|
| -}
|
| -
|
| -void MatlabLine::Append(double x, double y)
|
| -{
|
| - if (_maxLen > 0 && _xData.size() > static_cast<uint32_t>(_maxLen))
|
| - {
|
| - _xData.resize(_maxLen);
|
| - _yData.resize(_maxLen);
|
| - }
|
| -
|
| - _xData.push_front(x);
|
| - _yData.push_front(y);
|
| -}
|
| -
|
| -
|
| -// append y-data with running integer index as x-data
|
| -void MatlabLine::Append(double y)
|
| -{
|
| - if (_xData.empty())
|
| - {
|
| - // first element is index 0
|
| - Append(0, y);
|
| - }
|
| - else
|
| - {
|
| - // take last x-value and increment
|
| - double temp = _xData.back(); // last x-value
|
| - Append(temp + 1, y);
|
| - }
|
| -}
|
| -
|
| -
|
| -void MatlabLine::SetMaxLen(int maxLen)
|
| -{
|
| - if (maxLen <= 0)
|
| - {
|
| - // means no maxLen
|
| - _maxLen = -1;
|
| - }
|
| - else
|
| - {
|
| - _maxLen = maxLen;
|
| -
|
| - if (_xArray != NULL)
|
| - {
|
| - mxDestroyArray(_xArray);
|
| - mxDestroyArray(_yArray);
|
| - }
|
| - _xArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL);
|
| - _yArray = mxCreateDoubleMatrix(1, _maxLen, mxREAL);
|
| -
|
| - maxLen = ((unsigned int)maxLen <= _xData.size()) ? maxLen : (int)_xData.size();
|
| - _xData.resize(maxLen);
|
| - _yData.resize(maxLen);
|
| -
|
| - //// reserve the right amount of memory
|
| - //_xData.reserve(_maxLen);
|
| - //_yData.reserve(_maxLen);
|
| - }
|
| -}
|
| -
|
| -void MatlabLine::SetAttribute(char *plotAttrib)
|
| -{
|
| - _plotAttribute = plotAttrib;
|
| -}
|
| -
|
| -void MatlabLine::SetName(char *name)
|
| -{
|
| - _name = name;
|
| -}
|
| -
|
| -void MatlabLine::GetPlotData(mxArray** xData, mxArray** yData)
|
| -{
|
| - // Make sure we have enough Matlab allocated memory.
|
| - // Assuming both arrays (x and y) are of the same size.
|
| - if (_xData.empty())
|
| - {
|
| - return; // No data
|
| - }
|
| - unsigned int size = 0;
|
| - if (_xArray != NULL)
|
| - {
|
| - size = (unsigned int)mxGetNumberOfElements(_xArray);
|
| - }
|
| - if (size < _xData.size())
|
| - {
|
| - if (_xArray != NULL)
|
| - {
|
| - mxDestroyArray(_xArray);
|
| - mxDestroyArray(_yArray);
|
| - }
|
| - _xArray = mxCreateDoubleMatrix(1, _xData.size(), mxREAL);
|
| - _yArray = mxCreateDoubleMatrix(1, _yData.size(), mxREAL);
|
| - }
|
| -
|
| - if (!_xData.empty())
|
| - {
|
| - double* x = mxGetPr(_xArray);
|
| -
|
| - std::list<double>::iterator it = _xData.begin();
|
| -
|
| - for (int i = 0; it != _xData.end(); it++, i++)
|
| - {
|
| - x[i] = *it;
|
| - }
|
| - }
|
| -
|
| - if (!_yData.empty())
|
| - {
|
| - double* y = mxGetPr(_yArray);
|
| -
|
| - std::list<double>::iterator it = _yData.begin();
|
| -
|
| - for (int i = 0; it != _yData.end(); it++, i++)
|
| - {
|
| - y[i] = *it;
|
| - }
|
| - }
|
| - *xData = _xArray;
|
| - *yData = _yArray;
|
| -}
|
| -
|
| -std::string MatlabLine::GetXName()
|
| -{
|
| - std::ostringstream xString;
|
| - xString << "x_" << _name;
|
| - return xString.str();
|
| -}
|
| -
|
| -std::string MatlabLine::GetYName()
|
| -{
|
| - std::ostringstream yString;
|
| - yString << "y_" << _name;
|
| - return yString.str();
|
| -}
|
| -
|
| -std::string MatlabLine::GetPlotString()
|
| -{
|
| -
|
| - std::ostringstream s;
|
| -
|
| - if (_xData.size() == 0)
|
| - {
|
| - s << "[0 1], [0 1]"; // To get an empty plot
|
| - }
|
| - else
|
| - {
|
| - s << GetXName() << "(1:" << _xData.size() << "),";
|
| - s << GetYName() << "(1:" << _yData.size() << ")";
|
| - }
|
| -
|
| - s << ", '";
|
| - s << _plotAttribute;
|
| - s << "'";
|
| -
|
| - return s.str();
|
| -}
|
| -
|
| -std::string MatlabLine::GetRefreshString()
|
| -{
|
| - std::ostringstream s;
|
| -
|
| - if (_xData.size() > 0)
|
| - {
|
| - s << "set(h,'xdata',"<< GetXName() <<"(1:" << _xData.size() << "),'ydata',"<< GetYName() << "(1:" << _yData.size() << "));";
|
| - }
|
| - else
|
| - {
|
| - s << "set(h,'xdata',[NaN],'ydata',[NaN]);";
|
| - }
|
| - return s.str();
|
| -}
|
| -
|
| -std::string MatlabLine::GetLegendString()
|
| -{
|
| - return ("'" + _name + "'");
|
| -}
|
| -
|
| -bool MatlabLine::hasLegend()
|
| -{
|
| - return (!_name.empty());
|
| -}
|
| -
|
| -
|
| -// remove data points, but keep attributes
|
| -void MatlabLine::Reset()
|
| -{
|
| - _xData.clear();
|
| - _yData.clear();
|
| -}
|
| -
|
| -
|
| -void MatlabLine::UpdateTrendLine(MatlabLine * sourceData, double slope, double offset)
|
| -{
|
| - Reset(); // reset data, not attributes and name
|
| -
|
| - double thexMin = sourceData->xMin();
|
| - double thexMax = sourceData->xMax();
|
| - Append(thexMin, thexMin * slope + offset);
|
| - Append(thexMax, thexMax * slope + offset);
|
| -}
|
| -
|
| -double MatlabLine::xMin()
|
| -{
|
| - if (!_xData.empty())
|
| - {
|
| - std::list<double>::iterator theStart = _xData.begin();
|
| - std::list<double>::iterator theEnd = _xData.end();
|
| - return(*min_element(theStart, theEnd));
|
| - }
|
| - return (0.0);
|
| -}
|
| -
|
| -double MatlabLine::xMax()
|
| -{
|
| - if (!_xData.empty())
|
| - {
|
| - std::list<double>::iterator theStart = _xData.begin();
|
| - std::list<double>::iterator theEnd = _xData.end();
|
| - return(*max_element(theStart, theEnd));
|
| - }
|
| - return (0.0);
|
| -}
|
| -
|
| -double MatlabLine::yMin()
|
| -{
|
| - if (!_yData.empty())
|
| - {
|
| - std::list<double>::iterator theStart = _yData.begin();
|
| - std::list<double>::iterator theEnd = _yData.end();
|
| - return(*min_element(theStart, theEnd));
|
| - }
|
| - return (0.0);
|
| -}
|
| -
|
| -double MatlabLine::yMax()
|
| -{
|
| - if (!_yData.empty())
|
| - {
|
| - std::list<double>::iterator theStart = _yData.begin();
|
| - std::list<double>::iterator theEnd = _yData.end();
|
| - return(*max_element(theStart, theEnd));
|
| - }
|
| - return (0.0);
|
| -}
|
| -
|
| -
|
| -
|
| -MatlabTimeLine::MatlabTimeLine(int horizonSeconds /*= -1*/, const char *plotAttrib /*= NULL*/,
|
| - const char *name /*= NULL*/,
|
| - int64_t refTimeMs /* = -1*/)
|
| - :
|
| -_timeHorizon(horizonSeconds),
|
| -MatlabLine(-1, plotAttrib, name) // infinite number of elements
|
| -{
|
| - if (refTimeMs < 0)
|
| - _refTimeMs = TickTime::MillisecondTimestamp();
|
| - else
|
| - _refTimeMs = refTimeMs;
|
| -}
|
| -
|
| -void MatlabTimeLine::Append(double y)
|
| -{
|
| - MatlabLine::Append(static_cast<double>(TickTime::MillisecondTimestamp() - _refTimeMs) / 1000.0, y);
|
| -
|
| - PurgeOldData();
|
| -}
|
| -
|
| -
|
| -void MatlabTimeLine::PurgeOldData()
|
| -{
|
| - if (_timeHorizon > 0)
|
| - {
|
| - // remove old data
|
| - double historyLimit = static_cast<double>(TickTime::MillisecondTimestamp() - _refTimeMs) / 1000.0
|
| - - _timeHorizon; // remove data points older than this
|
| -
|
| - std::list<double>::reverse_iterator ritx = _xData.rbegin();
|
| - uint32_t removeCount = 0;
|
| - while (ritx != _xData.rend())
|
| - {
|
| - if (*ritx >= historyLimit)
|
| - {
|
| - break;
|
| - }
|
| - ritx++;
|
| - removeCount++;
|
| - }
|
| - if (removeCount == 0)
|
| - {
|
| - return;
|
| - }
|
| -
|
| - // remove the range [begin, it).
|
| - //if (removeCount > 10)
|
| - //{
|
| - // printf("Removing %lu elements\n", removeCount);
|
| - //}
|
| - _xData.resize(_xData.size() - removeCount);
|
| - _yData.resize(_yData.size() - removeCount);
|
| - }
|
| -}
|
| -
|
| -
|
| -int64_t MatlabTimeLine::GetRefTime()
|
| -{
|
| - return(_refTimeMs);
|
| -}
|
| -
|
| -
|
| -
|
| -
|
| -MatlabPlot::MatlabPlot()
|
| -:
|
| -_figHandle(-1),
|
| -_smartAxis(false),
|
| -_critSect(CriticalSectionWrapper::CreateCriticalSection()),
|
| -_timeToPlot(false),
|
| -_plotting(false),
|
| -_enabled(true),
|
| -_firstPlot(true),
|
| -_legendEnabled(true),
|
| -_donePlottingEvent(EventWrapper::Create())
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - _xlim[0] = 0;
|
| - _xlim[1] = 0;
|
| - _ylim[0] = 0;
|
| - _ylim[1] = 0;
|
| -
|
| -#ifdef PLOT_TESTING
|
| - _plotStartTime = -1;
|
| - _plotDelay = 0;
|
| -#endif
|
| -
|
| -}
|
| -
|
| -
|
| -MatlabPlot::~MatlabPlot()
|
| -{
|
| - _critSect->Enter();
|
| -
|
| - // delete all line objects
|
| - while (!_line.empty())
|
| - {
|
| - delete *(_line.end() - 1);
|
| - _line.pop_back();
|
| - }
|
| -
|
| - delete _critSect;
|
| - delete _donePlottingEvent;
|
| -}
|
| -
|
| -
|
| -int MatlabPlot::AddLine(int maxLen /*= -1*/, const char *plotAttrib /*= NULL*/, const char *name /*= NULL*/)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| - if (!_enabled)
|
| - {
|
| - return -1;
|
| - }
|
| -
|
| - MatlabLine *newLine = new MatlabLine(maxLen, plotAttrib, name);
|
| - _line.push_back(newLine);
|
| -
|
| - return (static_cast<int>(_line.size() - 1)); // index of newly inserted line
|
| -}
|
| -
|
| -
|
| -int MatlabPlot::AddTimeLine(int maxLen /*= -1*/, const char *plotAttrib /*= NULL*/, const char *name /*= NULL*/,
|
| - int64_t refTimeMs /*= -1*/)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - if (!_enabled)
|
| - {
|
| - return -1;
|
| - }
|
| -
|
| - MatlabTimeLine *newLine = new MatlabTimeLine(maxLen, plotAttrib, name, refTimeMs);
|
| - _line.push_back(newLine);
|
| -
|
| - return (static_cast<int>(_line.size() - 1)); // index of newly inserted line
|
| -}
|
| -
|
| -
|
| -int MatlabPlot::GetLineIx(const char *name)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - if (!_enabled)
|
| - {
|
| - return -1;
|
| - }
|
| -
|
| - // search the list for a matching line name
|
| - std::vector<MatlabLine*>::iterator it = _line.begin();
|
| - bool matchFound = false;
|
| - int lineIx = 0;
|
| -
|
| - for (; it != _line.end(); it++, lineIx++)
|
| - {
|
| - if ((*it)->_name == name)
|
| - {
|
| - matchFound = true;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - if (matchFound)
|
| - {
|
| - return (lineIx);
|
| - }
|
| - else
|
| - {
|
| - return (-1);
|
| - }
|
| -}
|
| -
|
| -
|
| -void MatlabPlot::Append(int lineIndex, double x, double y)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - if (!_enabled)
|
| - {
|
| - return;
|
| - }
|
| -
|
| - // sanity for index
|
| - if (lineIndex < 0 || lineIndex >= static_cast<int>(_line.size()))
|
| - {
|
| - throw "Line index out of range";
|
| - exit(1);
|
| - }
|
| -
|
| - return (_line[lineIndex]->Append(x, y));
|
| -}
|
| -
|
| -
|
| -void MatlabPlot::Append(int lineIndex, double y)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - if (!_enabled)
|
| - {
|
| - return;
|
| - }
|
| -
|
| - // sanity for index
|
| - if (lineIndex < 0 || lineIndex >= static_cast<int>(_line.size()))
|
| - {
|
| - throw "Line index out of range";
|
| - exit(1);
|
| - }
|
| -
|
| - return (_line[lineIndex]->Append(y));
|
| -}
|
| -
|
| -
|
| -int MatlabPlot::Append(const char *name, double x, double y)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - if (!_enabled)
|
| - {
|
| - return -1;
|
| - }
|
| -
|
| - // search the list for a matching line name
|
| - int lineIx = GetLineIx(name);
|
| -
|
| - if (lineIx < 0) //(!matchFound)
|
| - {
|
| - // no match; append new line
|
| - lineIx = AddLine(-1, NULL, name);
|
| - }
|
| -
|
| - // append data to line
|
| - Append(lineIx, x, y);
|
| - return (lineIx);
|
| -}
|
| -
|
| -int MatlabPlot::Append(const char *name, double y)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - if (!_enabled)
|
| - {
|
| - return -1;
|
| - }
|
| -
|
| - // search the list for a matching line name
|
| - int lineIx = GetLineIx(name);
|
| -
|
| - if (lineIx < 0) //(!matchFound)
|
| - {
|
| - // no match; append new line
|
| - lineIx = AddLine(-1, NULL, name);
|
| - }
|
| -
|
| - // append data to line
|
| - Append(lineIx, y);
|
| - return (lineIx);
|
| -}
|
| -
|
| -int MatlabPlot::Length(char *name)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - if (!_enabled)
|
| - {
|
| - return -1;
|
| - }
|
| -
|
| - int ix = GetLineIx(name);
|
| - if (ix >= 0)
|
| - {
|
| - return (static_cast<int>(_line[ix]->_xData.size()));
|
| - }
|
| - else
|
| - {
|
| - return (-1);
|
| - }
|
| -}
|
| -
|
| -
|
| -void MatlabPlot::SetPlotAttribute(char *name, char *plotAttrib)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - if (!_enabled)
|
| - {
|
| - return;
|
| - }
|
| -
|
| - int lineIx = GetLineIx(name);
|
| -
|
| - if (lineIx >= 0)
|
| - {
|
| - _line[lineIx]->SetAttribute(plotAttrib);
|
| - }
|
| -}
|
| -
|
| -// Must be called under critical section _critSect
|
| -void MatlabPlot::UpdateData(Engine* ep)
|
| -{
|
| - if (!_enabled)
|
| - {
|
| - return;
|
| - }
|
| -
|
| - for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
|
| - {
|
| - mxArray* xData = NULL;
|
| - mxArray* yData = NULL;
|
| - (*it)->GetPlotData(&xData, &yData);
|
| - if (xData != NULL)
|
| - {
|
| - std::string xName = (*it)->GetXName();
|
| - std::string yName = (*it)->GetYName();
|
| - _critSect->Leave();
|
| -#ifdef MATLAB6
|
| - mxSetName(xData, xName.c_str());
|
| - mxSetName(yData, yName.c_str());
|
| - engPutArray(ep, xData);
|
| - engPutArray(ep, yData);
|
| -#else
|
| - int ret = engPutVariable(ep, xName.c_str(), xData);
|
| - assert(ret == 0);
|
| - ret = engPutVariable(ep, yName.c_str(), yData);
|
| - assert(ret == 0);
|
| -#endif
|
| - _critSect->Enter();
|
| - }
|
| - }
|
| -}
|
| -
|
| -bool MatlabPlot::GetPlotCmd(std::ostringstream & cmd, Engine* ep)
|
| -{
|
| - _critSect->Enter();
|
| -
|
| - if (!DataAvailable())
|
| - {
|
| - return false;
|
| - }
|
| -
|
| - if (_firstPlot)
|
| - {
|
| - GetPlotCmd(cmd);
|
| - _firstPlot = false;
|
| - }
|
| - else
|
| - {
|
| - GetRefreshCmd(cmd);
|
| - }
|
| -
|
| - UpdateData(ep);
|
| -
|
| - _critSect->Leave();
|
| -
|
| - return true;
|
| -}
|
| -
|
| -// Call inside critsect
|
| -void MatlabPlot::GetPlotCmd(std::ostringstream & cmd)
|
| -{
|
| - // we have something to plot
|
| - // empty the stream
|
| - cmd.str(""); // (this seems to be the only way)
|
| -
|
| - cmd << "figure; h" << _figHandle << "= plot(";
|
| -
|
| - // first line
|
| - std::vector<MatlabLine*>::iterator it = _line.begin();
|
| - cmd << (*it)->GetPlotString();
|
| -
|
| - it++;
|
| -
|
| - // remaining lines
|
| - for (; it != _line.end(); it++)
|
| - {
|
| - cmd << ", ";
|
| - cmd << (*it)->GetPlotString();
|
| - }
|
| -
|
| - cmd << "); ";
|
| -
|
| - if (_legendEnabled)
|
| - {
|
| - GetLegendCmd(cmd);
|
| - }
|
| -
|
| - if (_smartAxis)
|
| - {
|
| - double xMin = _xlim[0];
|
| - double xMax = _xlim[1];
|
| - double yMax = _ylim[1];
|
| - for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
|
| - {
|
| - xMax = std::max(xMax, (*it)->xMax());
|
| - xMin = std::min(xMin, (*it)->xMin());
|
| -
|
| - yMax = std::max(yMax, (*it)->yMax());
|
| - yMax = std::max(yMax, fabs((*it)->yMin()));
|
| - }
|
| - _xlim[0] = xMin;
|
| - _xlim[1] = xMax;
|
| - _ylim[0] = -yMax;
|
| - _ylim[1] = yMax;
|
| -
|
| - cmd << "axis([" << _xlim[0] << ", " << _xlim[1] << ", " << _ylim[0] << ", " << _ylim[1] << "]);";
|
| - }
|
| -
|
| - int i=1;
|
| - for (it = _line.begin(); it != _line.end(); i++, it++)
|
| - {
|
| - cmd << "set(h" << _figHandle << "(" << i << "), 'Tag', " << (*it)->GetLegendString() << ");";
|
| - }
|
| -}
|
| -
|
| -// Call inside critsect
|
| -void MatlabPlot::GetRefreshCmd(std::ostringstream & cmd)
|
| -{
|
| - cmd.str(""); // (this seems to be the only way)
|
| - std::vector<MatlabLine*>::iterator it = _line.begin();
|
| - for (it = _line.begin(); it != _line.end(); it++)
|
| - {
|
| - cmd << "h = findobj(0, 'Tag', " << (*it)->GetLegendString() << ");";
|
| - cmd << (*it)->GetRefreshString();
|
| - }
|
| - //if (_legendEnabled)
|
| - //{
|
| - // GetLegendCmd(cmd);
|
| - //}
|
| -}
|
| -
|
| -void MatlabPlot::GetLegendCmd(std::ostringstream & cmd)
|
| -{
|
| - std::vector<MatlabLine*>::iterator it = _line.begin();
|
| - bool anyLegend = false;
|
| - for (; it != _line.end(); it++)
|
| - {
|
| - anyLegend = anyLegend || (*it)->hasLegend();
|
| - }
|
| - if (anyLegend)
|
| - {
|
| - // create the legend
|
| -
|
| - cmd << "legend(h" << _figHandle << ",{";
|
| -
|
| -
|
| - // iterate lines
|
| - int i = 0;
|
| - for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
|
| - {
|
| - if (i > 0)
|
| - {
|
| - cmd << ", ";
|
| - }
|
| - cmd << (*it)->GetLegendString();
|
| - i++;
|
| - }
|
| -
|
| - cmd << "}, 2); "; // place legend in upper-left corner
|
| - }
|
| -}
|
| -
|
| -// Call inside critsect
|
| -bool MatlabPlot::DataAvailable()
|
| -{
|
| - if (!_enabled)
|
| - {
|
| - return false;
|
| - }
|
| -
|
| - for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
|
| - {
|
| - (*it)->PurgeOldData();
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void MatlabPlot::Plot()
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - _timeToPlot = true;
|
| -
|
| -#ifdef PLOT_TESTING
|
| - _plotStartTime = TickTime::MillisecondTimestamp();
|
| -#endif
|
| -}
|
| -
|
| -
|
| -void MatlabPlot::Reset()
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - _enabled = true;
|
| -
|
| - for (std::vector<MatlabLine*>::iterator it = _line.begin(); it != _line.end(); it++)
|
| - {
|
| - (*it)->Reset();
|
| - }
|
| -
|
| -}
|
| -
|
| -void MatlabPlot::SetFigHandle(int handle)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - if (handle > 0)
|
| - _figHandle = handle;
|
| -}
|
| -
|
| -bool
|
| -MatlabPlot::TimeToPlot()
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| - return _enabled && _timeToPlot;
|
| -}
|
| -
|
| -void
|
| -MatlabPlot::Plotting()
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| - _plotting = true;
|
| -}
|
| -
|
| -void
|
| -MatlabPlot::DonePlotting()
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| - _timeToPlot = false;
|
| - _plotting = false;
|
| - _donePlottingEvent->Set();
|
| -}
|
| -
|
| -void
|
| -MatlabPlot::DisablePlot()
|
| -{
|
| - _critSect->Enter();
|
| - while (_plotting)
|
| - {
|
| - _critSect->Leave();
|
| - _donePlottingEvent->Wait(WEBRTC_EVENT_INFINITE);
|
| - _critSect->Enter();
|
| - }
|
| - _enabled = false;
|
| -}
|
| -
|
| -int MatlabPlot::MakeTrend(const char *sourceName, const char *trendName, double slope, double offset, const char *plotAttrib)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - int sourceIx;
|
| - int trendIx;
|
| -
|
| - sourceIx = GetLineIx(sourceName);
|
| - if (sourceIx < 0)
|
| - {
|
| - // could not find source
|
| - return (-1);
|
| - }
|
| -
|
| - trendIx = GetLineIx(trendName);
|
| - if (trendIx < 0)
|
| - {
|
| - // no trend found; add new line
|
| - trendIx = AddLine(2 /*maxLen*/, plotAttrib, trendName);
|
| - }
|
| -
|
| - _line[trendIx]->UpdateTrendLine(_line[sourceIx], slope, offset);
|
| -
|
| - return (trendIx);
|
| -
|
| -}
|
| -
|
| -
|
| -MatlabEngine::MatlabEngine()
|
| -:
|
| -_critSect(CriticalSectionWrapper::CreateCriticalSection()),
|
| -_eventPtr(NULL),
|
| -_running(false),
|
| -_numPlots(0)
|
| -{
|
| - _eventPtr = EventWrapper::Create();
|
| -
|
| - _plotThread(MatlabEngine::PlotThread, this,
|
| - kLowPriority, "MatlabPlot");
|
| - _running = true;
|
| - _plotThread->Start();
|
| -}
|
| -
|
| -MatlabEngine::~MatlabEngine()
|
| -{
|
| - _critSect->Enter();
|
| -
|
| - if (_plotThread)
|
| - {
|
| - _running = false;
|
| - _eventPtr->Set();
|
| -
|
| - _plotThread->Stop();
|
| - }
|
| -
|
| - _plots.clear();
|
| -
|
| - delete _eventPtr;
|
| - _eventPtr = NULL;
|
| -
|
| - _critSect->Leave();
|
| - delete _critSect;
|
| -
|
| -}
|
| -
|
| -MatlabPlot * MatlabEngine::NewPlot(MatlabPlot *newPlot)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - //MatlabPlot *newPlot = new MatlabPlot();
|
| -
|
| - if (newPlot)
|
| - {
|
| - newPlot->SetFigHandle(++_numPlots); // first plot is number 1
|
| - _plots.push_back(newPlot);
|
| - }
|
| -
|
| - return (newPlot);
|
| -
|
| -}
|
| -
|
| -
|
| -void MatlabEngine::DeletePlot(MatlabPlot *plot)
|
| -{
|
| - CriticalSectionScoped cs(_critSect);
|
| -
|
| - if (plot == NULL)
|
| - {
|
| - return;
|
| - }
|
| -
|
| - std::vector<MatlabPlot *>::iterator it;
|
| - for (it = _plots.begin(); it < _plots.end(); it++)
|
| - {
|
| - if (plot == *it)
|
| - {
|
| - break;
|
| - }
|
| - }
|
| -
|
| - assert (plot == *it);
|
| -
|
| - (*it)->DisablePlot();
|
| -
|
| - _plots.erase(it);
|
| - --_numPlots;
|
| -
|
| - delete plot;
|
| -}
|
| -
|
| -
|
| -bool MatlabEngine::PlotThread(void *obj)
|
| -{
|
| - if (!obj)
|
| - {
|
| - return (false);
|
| - }
|
| -
|
| - MatlabEngine *eng = (MatlabEngine *) obj;
|
| -
|
| - Engine *ep = engOpen(NULL);
|
| - if (!ep)
|
| - {
|
| - throw "Cannot open Matlab engine";
|
| - return (false);
|
| - }
|
| -
|
| - engSetVisible(ep, true);
|
| - engEvalString(ep, "close all;");
|
| -
|
| - while (eng->_running)
|
| - {
|
| - eng->_critSect->Enter();
|
| -
|
| - // iterate through all plots
|
| - for (unsigned int ix = 0; ix < eng->_plots.size(); ix++)
|
| - {
|
| - MatlabPlot *plot = eng->_plots[ix];
|
| - if (plot->TimeToPlot())
|
| - {
|
| - plot->Plotting();
|
| - eng->_critSect->Leave();
|
| - std::ostringstream cmd;
|
| -
|
| - if (engEvalString(ep, cmd.str().c_str()))
|
| - {
|
| - // engine dead
|
| - return (false);
|
| - }
|
| -
|
| - // empty the stream
|
| - cmd.str(""); // (this seems to be the only way)
|
| - if (plot->GetPlotCmd(cmd, ep))
|
| - {
|
| - // things to plot, we have already accessed what we need in the plot
|
| - plot->DonePlotting();
|
| -
|
| - int64_t start = TickTime::MillisecondTimestamp();
|
| - // plot it
|
| - int ret = engEvalString(ep, cmd.str().c_str());
|
| - printf("time=%I64i\n", TickTime::MillisecondTimestamp() - start);
|
| - if (ret)
|
| - {
|
| - // engine dead
|
| - return (false);
|
| - }
|
| -
|
| -#ifdef PLOT_TESTING
|
| - if(plot->_plotStartTime >= 0)
|
| - {
|
| - plot->_plotDelay = TickTime::MillisecondTimestamp() - plot->_plotStartTime;
|
| - plot->_plotStartTime = -1;
|
| - }
|
| -#endif
|
| - }
|
| - eng->_critSect->Enter();
|
| - }
|
| - }
|
| -
|
| - eng->_critSect->Leave();
|
| - // wait a while
|
| - eng->_eventPtr->Wait(66); // 33 ms
|
| - }
|
| -
|
| - if (ep)
|
| - {
|
| - engClose(ep);
|
| - ep = NULL;
|
| - }
|
| -
|
| - return (true);
|
| -
|
| -}
|
| -
|
| -#endif // MATLAB
|
|
|