00001 #include "datastream_sample.h" 00002 #include <QTextStream> 00003 #include <QFile> 00004 #include <QMessageBox> 00005 #include <QDebug> 00006 #include <thread> 00007 #include <mutex> 00008 #include <chrono> 00009 #include <thread> 00010 #include <math.h> 00011 00012 DataStreamSample::DataStreamSample(): 00013 _enabled(false) 00014 { 00015 QStringList words_list; 00016 words_list << "siam" << "tre" << "piccoli" << "porcellin" 00017 << "mai" << "nessun" << "ci" << "dividera" << "_sin" << "_cos"; 00018 00019 int N = words_list.size(); 00020 00021 foreach( const QString& name, words_list) 00022 { 00023 DataStreamSample::Parameters param; 00024 if(name == "_sin"){ 00025 param.A = 2; 00026 param.B = 1; 00027 param.C = 0; 00028 param.D = 0; 00029 } 00030 else if (name == "_cos"){ 00031 param.A = 2; 00032 param.B = 1; 00033 param.C = 1.5708; 00034 param.D = 0; 00035 } 00036 else{ 00037 param.A = qrand()/(double)RAND_MAX * 6 - 3; 00038 param.B = qrand()/(double)RAND_MAX *3; 00039 param.C = qrand()/(double)RAND_MAX *3; 00040 param.D = qrand()/(double)RAND_MAX *2 -1; 00041 } 00042 00043 const std::string name_str = name.toStdString(); 00044 PlotDataPtr plot( new PlotData(name_str.c_str()) ); 00045 00046 _plot_data.numeric.insert( std::make_pair( name_str, plot) ); 00047 _parameters.insert( std::make_pair( name_str, param) ); 00048 } 00049 } 00050 00051 bool DataStreamSample::start(QString& default_configuration) 00052 { 00053 _running = true; 00054 pushSingleCycle(); 00055 _thread = std::thread([this](){ this->loop();} ); 00056 return true; 00057 } 00058 00059 void DataStreamSample::shutdown() 00060 { 00061 _running = false; 00062 if( _thread.joinable()) _thread.join(); 00063 } 00064 00065 void DataStreamSample::enableStreaming(bool enable) { _enabled = enable; } 00066 00067 bool DataStreamSample::isStreamingEnabled() const { return _enabled; } 00068 00069 DataStreamSample::~DataStreamSample() 00070 { 00071 shutdown(); 00072 } 00073 00074 void DataStreamSample::pushSingleCycle() 00075 { 00076 using namespace std::chrono; 00077 static std::chrono::high_resolution_clock::time_point initial_time = high_resolution_clock::now(); 00078 const double offset = duration_cast< duration<double>>( initial_time.time_since_epoch() ).count() ; 00079 00080 auto now = high_resolution_clock::now(); 00081 for (auto& it: _plot_data.numeric ) 00082 { 00083 auto par = _parameters[it.first]; 00084 00085 auto& plot = it.second; 00086 const double t = duration_cast< duration<double>>( now - initial_time ).count() ; 00087 double y = par.A*sin(par.B*t + par.C) + par.D*t*0.05; 00088 00089 // IMPORTANT: don't use pushBack(), it may cause a segfault 00090 plot->pushBackAsynchronously( PlotData::Point( t + offset, y ) ); 00091 } 00092 } 00093 00094 void DataStreamSample::loop() 00095 { 00096 _running = true; 00097 while( _running ) 00098 { 00099 PlotData::asyncPushMutex().lock(); 00100 if( _enabled ){ 00101 pushSingleCycle(); 00102 } 00103 PlotData::asyncPushMutex().unlock(); 00104 std::this_thread::sleep_for ( std::chrono::milliseconds(10) ); 00105 } 00106 }