QCustomPlot in real time in an ECG style - c++

I want to make a real time graph to plot the data from my Arduino and I want to use the following function from QCustomPlot to plot the graph in an ECG style (starting again after few seconds and replacing the previous data):
void QCPGraph::addData(const QVector<double> &keys, const QVector<double> &values)`
with keys=time and values=data from serial port.
I already have the serial data and a graph that is continuous but I don't know how to modify this with the function above and make time vector.
Can you give me an example of how to call that function?

If I get it right, you have a graph that it's xAxis range is constant. Lets say it is defined as MAX_RANGE seconds, and you want that once it passes MAX_RANGE seconds it will clear the graph and start over again from 0 sec.
If all this is right then I guess you already have a function that you are calling once every T seconds in order to update the plot. If not then take a look at this example.
Lets assume that you already have a function that you are calling every T seconds:
void MyPlot::updatePlot(int yValue)
Then simply add a timeCounter as a class variable that will be updated every call. Then add an if statement that will check if it passed MAX_RANGE. If it did then clear the graph using clearData(), add the new value and reset timeCounter. If it didn't then just add the new value. Simple example (just make the changes to fit for your case):
void MyPlot::updatePlot(int yValue){
this->timeCounter += T;
if (this->timeCounter >= MAX_RANGE) {
ui->customPlot->graph(0)->clearData();
ui->customPlot->graph(0)->addData(0, yValue);
this->timeCounter = 0;
}
else {
ui->customPlot->graph(0)->addData(this->timeCounter, yValue);
}
}

Related

Variable resetting problem in a list of objects

Today I was writing some SDL C++ program, with squares called particles. My problem is that, for some reason, variable y in instances of class Particle is always resetting to the value passed into the constructor after incrementing it by 1. I'm storing the objects in a list.
That's a method that's called every frame:
void everyFrame(){
this->y+=1;
std::cout<<"update y: "<<this->y<<std::endl;
}
And this method is also called every frame, after the everyFrame() method:
void blit(){
this->rect.x=this->x*10;
this->rect.y=this->y*10;
std::cout<<"blitting y: "<<this->y<<std::endl;
SDL_BlitSurface(this->image,NULL,screen,&this->rect);
}
This is the part of the code, where I'm adding an object/objects to the list:
std::list<Particle> particles;
particles.push_back(Particle(2,10,5));
And there I'm executing these 2 methods in the main loop:
for(Particle x:particles){
x.everyFrame();
}
for(Particle x:particles){
x.blit();
}
The console output of the program when y 5 is passed into the constructor is just:
update y: 6
blitting y: 5
looped around.
I also found out that when I'm storing an object in a normal variable, not in a list, then it works. Is there any reason/fix for it not working in a list?
These lines:
for(Particle x:particles){
x.everyFrame();
}
are not modifying the particles list.
This is because Particle x:particles is creating a copy of each element before calling x.everyFrame().
You need to change it to:
for(Particle & x:particles){ // NOTE: added &
x.everyFrame();
}
Taking a refernce to the list element will modify the element in the list.
The same applied to the second loop applying blit().
A side note:
Using the auto keywoard is usually recomended in this case. You need to keep in mind that auto does not include CV qualifiers, and pointerness/referenceness. Therefore you need:
for(auto & x:particles){ ... }
And if you are traversing a container without modifying the elements, it is rcomended to use:
for(auto const & x:particles){ ... }

C++ Variable contents being lost between 2 functions [Unreal]

Greetings fellow programmers.
I've been struggeling with learning c++ within the Unreal engine. I thought I understood how to track time properly within a class but alas my variable is chaning it's contents to a vastly different number in the time between two function calls.
For context there are a small number of objects present:
Global Time system
This class is responsible for managing the time and receiving update ticks from the time watcher. This is also a singleton!
TimeWatcher
Super simple, just a Uobject I spawn into the world so it can receive update ticks from the engine and pass them onto the Global Time system
Time class
A class to hold the hours, minutes and seconds. How it is used beyond that is up to the developer using the class. In my case I am simply trying to store it and from that point on remove time off of it to create a countdown timer.
We have our own little logging system to help debugging along, mainly to generate logs without all the unreal stuff and in a format we prefer. This log outputs the following data:
<Log, TimerSystem> [2] 2019.03.17-17.41.42: init attempt, init time should be: 23:6.0
<Log, TimerSystem> [3] 2019.03.17-17.41.42: init attempt succes, 23:6.0
<Log, TimerSystem> [6] 2019.03.17-17.41.42: Timer tick occured, lets see what our timer thinks about the time -225161083:32766:00
So from this we can interpret that the variable in the scope it gets set in(shown below) is set there properly. But the moment we try to read it again in the handleTick function the variable is all wrong.
InitTimer function:
void GlobalTimerSystem::InitTimer(UWorld* world, Time* initialTime)
{
DebugUtility::WriteLog("init attempt, init time should be: " + initialTime->ToString(), DebugUtility::Log, DebugUtility::TimerSystem);
check(world);
//create timeWatcher in the world
FVector location(0.0f, 0.0f, 0.0f);
FRotator rotation(0.0f, 0.0f, 0.0f);
FActorSpawnParameters SpawnInfo;
world->SpawnActor<ATimeWatcher>(location, rotation, SpawnInfo);
//set current time to init value
Time* trPointer = new Time(initialTime->GetHours(), initialTime->GetMinutes(), initialTime->GetSeconds());
this->timeRemaining = *trPointer;
DebugUtility::WriteLog("init attempt succes, " + timeRemaining.ToString(), DebugUtility::Log, DebugUtility::TimerSystem);
}
There is some stupid pointer crap I am doing here, partly because of desperation at this point though.
The Handle tick function:
void GlobalTimerSystem::HandleTimerTick(float deltaTime)
{
DebugUtility::WriteLog("Timer tick occured, lets see what our timer thinks about the time " + timeRemaining.ToString(), DebugUtility::Log, DebugUtility::TimerSystem);
ticksReceived++;
FString debug2;
debug2.Append("Ticks received: ");
debug2.AppendInt(ticksReceived);
DebugUtility::WriteLog(debug2, DebugUtility::Log, DebugUtility::TimerSystem);
double t = static_cast<double>(deltaTime);
DecreaseTimer(&t);
if (deltaTime != NULL) {
FString debug;
debug.Append(TEXT("current time remaining is "));
debug.Append(*timeRemaining.ToString());
DebugUtility::WriteLog(debug, DebugUtility::Log, DebugUtility::TimerSystem);
}
}
Now we know things are already wrong the moment we enter the above function. For good measure here is the header file for this class.
class PGT_PROJECT_API GlobalTimerSystem
{
friend class ATimeWatcher;
private:
Time timeRemaining;
Time timeElapsedNotPaused;
Time timeElapsedPaused;
UINT ticksReceived = 0;
bool paused = false;
bool initComplete = false;
void HandleTimerTick(float deltaTime);
static GlobalTimerSystem* timerSystem;
public:
static GlobalTimerSystem* GetTimerSystem();
void InitTimer(UWorld* world, Time* initialTime);
void IncreaseTimer(double* additionalSeconds);
void DecreaseTimer(double* removeSeconds);
double GetTimeRemaining();
double GetTimeElapsed();
GlobalTimerSystem();
~GlobalTimerSystem();
};
If any more information is required I will be happy to provide. Thank you for your time!
EDIT:
I am overloading the Time::operator= which appears as follows:
Time & Time::operator=(Time & t)
{
_seconds = t._seconds;
_minutes = t._minutes;
_hours = t._hours;
return *this;
}
And using it as follows:
this->timeRemaining = Time(initialTime->GetHours(), initialTime->GetMinutes(), initialTime->GetSeconds());
However this results in the following compiler error that I do not understand:
Path...\Private\GlobalTimerSystem.cpp(62) : error C4239: nonstandard extension used: 'argument': conversion from 'Time' to 'Time &'
In GlobalTimerSystem::InitTimer(UWorld*, Time*), you do the following:
Time* trPointer = new Time(initialTime->GetHours(),
initialTime->GetMinutes(),
initialTime->GetSeconds());
this->timeRemaining = trPointer;
which means:
Create a new object of type Time on the heap, construct it with the following arguments and, once it's ready, return a pointer to it (Time*) which I'll store in my local variable trPointer;
assign the value of the pointer trPointer (which is the address of the instance of the class Time that we just allocated and initialized on the heap) to my instance variable timeRemaining (which is an instance of the class Time).
So once you reach GlobalTimerSystem::HandleTimerTick, this->timeRemaining contains garbage which stays garbage when translated ToString (hence the -225161083:32766:00 you see). Furthermore, the memory you now have allocated on the heap for that instance of Time you've created is wasted as you will never release it and won't even use it.
The thing is that, in this case, you don't need the heap at all!
Depending on how operator= behaves (you said you overloaded it), you should be able to do:
this->timeRemaining = Time(initialTime->GetHours(),
initialTime->GetMinutes(),
initialTime->GetSeconds());
which will create a temporary Time instance and initialize it with the passed arguments, then "copy" it (=) inside your instance variable timeRemaining. If you do this, you might want to look into Time::operator=(Time&&) as that "temporary Time instance" is an rvalue. Please note that, in this case, we do not leak memory as everything is allocated on the stack and will be released when the function returns.
If this does not work, that means Time::operator= is not behaving as a proper "copy operator" and should be fixed. Another approach would be to manually set the hours, minutes and seconds fields of timeRemaining (if they are public or friend) or (much better), to have a method such as Time::set(/*hours, minutes, seconds*/) allowing you to this->timeRemaining->set(...).
Finally, once again depending on the internals of Time and how Time::operator= has been written, noticing that initialTime is itself a Time*, the "temporary intermediate Time instance" shouldn't even be needed, leading to the much simpler and more readable
this->timeRemaining = *initialTime;
As a conclusion, I believe your issue comes from the implementation of Time::operator=.

why doesn't work the else-branch with the set()-method?

Link to my sketch:
http://www.openprocessing.org/sketch/377417
void check(ship s){
float d = dist(s.getX(),s.getY(),this.posx,this.posy);
if (d <= this.radius){
s.setSpeed(0.5);
}
if (d > this.radius){
s.setSpeed(2);
}
}
When i delete the second if-statement, the ship reduces its speed but don't accelerate when the distance is greater than the obstacle's radius.
Something's wrong with the set-method?
In the future, please provide an MCVE directly in your post instead of making us go to external websites. Also, please use standard naming conventions: classes should start with an upper-case letter. While you're at it, standard formatting (indent your code) would help too.
That being said, your problem is caused by this: think about how you're calling your check() function. You call it for every obstacle. Then you set the speed of the ship based on the distance from that obstacle.
The problem is, say you only have two obstacles. The first obstacle is colliding with the ship, so you set its speed to 0.5. Then you check the second obstacle, which isn't colliding with the ship, so you set its speed back up to 2. In other words, you're only ever changing the ship's speed based on the last obstacle in the loop.
If you take out the call to setSpeed(2), then of course your ship will never change speed back to 2.
You need to refactor your code so that you set the speed to 0.5 if the ship is colliding with any obstacle. It might look something like this:
boolean collides = false;
for(Obstacle o : obstacles){
if(o.collidesWith(ship)){
collides = true;
break;
}
}
if(collides){
ship.setSpeed(.5);
}
else{
ship.setSpeed(2);
}

Benchmarking GLSL shaders to compare speed of alternative implementations

I want to plot two-dimensional function z = f(x,y) using OpenGL and GLSL shaders. I'd like to map the value of function to color using a colormap, but some colormaps are expressed using HSL or HSV colorspace (for example hue maps).
You can find (here and in other places) different alternative implementtions of hsv2rgb() in GLSL.
How can I benchmark those shaders (those functions) to find out which one is fastest?
Implement all alternatives you want to try and apply the usual benchmark suggestions:
Repeat the individual benchmark enough times to have a time is seconds (less is going to be subject to too much noise)
Repeat the benchmarks in the environments you want to run it in.
Try to have a setup as close to reality as possible (same background processes, etc).
Repeat the benchmark runs several times and disregard outliers.
Randomize the order of algorithms/tests between runs.
Make sure you disable caching for the section that you are testing (if it's applicable).
Since you include OpenGL solutions you should consider if you want to count data transfers as well. Make sure you flush the pipelines (opengl deffers some calls, but flush will wait until they are actually finished).
If the run-times are too close you can either say they are about the same or increase data size/repetitions to make the difference more prominent.
For having implemented color maps, I'd just recommend to use a texture.
Something like a 256x1 texture (1D texture are not supported in ES, if that matters to you) and then from the float result of f(x,y), just use that as the texture coordinate.
If you have a lot of points to plot, that's going to be faster than evaluating it in glsl each time and GPU are good at texturing :)
You need to be able to measure time of GL rendering first. I do it in C++ like this:
//------------------------------------------------------------------------------
class OpenGLtime
{
public:
unsigned int id[2];
OpenGLtime();
OpenGLtime(OpenGLtime& a);
~OpenGLtime();
OpenGLtime* operator = (const OpenGLtime *a);
//OpenGLtime* operator = (const OpenGLtime &a);
void _init();
void tbeg(); // mark start time for measure
void tend(); // mark end time for measure
double time(); // wait for measure and return time [s]
};
//------------------------------------------------------------------------------
OpenGLtime::OpenGLtime()
{
id[0]=0;
id[1]=0;
}
//------------------------------------------------------------------------------
OpenGLtime::OpenGLtime(OpenGLtime& a)
{
id[0]=0;
id[1]=0;
}
//------------------------------------------------------------------------------
OpenGLtime::~OpenGLtime()
{
}
//------------------------------------------------------------------------------
OpenGLtime* OpenGLtime::operator = (const OpenGLtime *a)
{
*this=*a;
return this;
}
//------------------------------------------------------------------------------
void OpenGLtime::_init()
{
// generate two queries
glGenQueries(2,id);
}
//------------------------------------------------------------------------------
void OpenGLtime::tbeg()
{
if (!id[0]) _init();
// issue the query
glQueryCounter(id[0],GL_TIMESTAMP);
}
//------------------------------------------------------------------------------
void OpenGLtime::tend()
{
if (!id[0]) _init();
// issue the query
glQueryCounter(id[1],GL_TIMESTAMP);
}
//------------------------------------------------------------------------------
double OpenGLtime::time()
{
if (!id[0]) { _init(); return 0.0; }
double dt;
GLuint64 t0,t1;
int _stop;
// wait until the results are available
for (_stop=0;!_stop;Sleep(1)) glGetQueryObjectiv(id[0],GL_QUERY_RESULT_AVAILABLE,&_stop);
for (_stop=0;!_stop;Sleep(1)) glGetQueryObjectiv(id[1],GL_QUERY_RESULT_AVAILABLE,&_stop);
// get query results
glGetQueryObjectui64v(id[0],GL_QUERY_RESULT,&t0);
glGetQueryObjectui64v(id[1],GL_QUERY_RESULT,&t1);
dt=double(t1)-double(t0); dt*=0.000000001;
return dt;
}
//------------------------------------------------------------------------------
Now you just use it like this:
// few variables
OpenGLtime tim;
double draw_time;
// measurement
tim.tbeg();
// here render your stuff using binded shader
tim.tend();
draw_time=tim.time(); // time the render took in [s] just output it somewhere so you can see it
Now you should create your rendering stuff. And can compare the runtimes directly.
As yo can see you will measure time of the whole rendering pass/call and not of a part of GLSL code. So you have to take that into account. I do not know any way to measure part of GLSL code directly. Instead you can measure time without the part in the question and with it ... and substract the times but the compiler optimizations could mess it up.

How to: TBB node with multiple asynchronous inputs and multiple outputs

I am new to Threading Building Blocks (TBB); I would need to implement the following logic with TBB nodes:
A node of type N receives two inputs; for instance:
1. std::vector // data
2. bool // flag
These inputs come asynchronously.
If the input is of type 1, process the data owned by the node of type N to produce two outputs, for instance:
a. std::vector
b. int
If the input is of type 2, process the data owned by the node of type N to produce one output, say a std::vector.
I have been trying to formulate the input part using a tbb::flow::or_node, and the output part using tbb::flow::multifunction_node.
If there is only one input and multiple outputs, this logic can be written with tbb::flow::multifunction_node (I tested, it works). If there is one output, and multiple inputs, I found example of code illustrating solutions. However, it is not clear to me how the case of multiple asynchronous inputs and multiple outputs can be implemented with the TBB framework. Suggestions welcome.
You should be able to do what you want with the current implementation of or_node. (We are re-designing the output of the or_node to make it more friendly, but we need input from users like you on issues with the or_node Community Preview Feature.)
One thing to remember is to turn on the CPF when you are compiling code with the or_node. The switch is -DTBB_PREVIEW_GRAPH_NODES=1 .
# define TBB_PREVIEW_GRAPH_NODES 1 // necessary to turn on the or_node community Preview Feature.
#include "tbb/flow_graph.h"
#include <vector>
using namespace tbb::flow;
// The output format of the or_node is a struct that contains
// 1. the index of the input that the message appeared on, and
// 2. a tuple, the (i-1)th element of which is the message received
typedef or_node<tuple<std::vector<double>, bool> > my_or_node_type;
// it wasn't clear from the description if you wanted to differentiate between the vectors output with
// an input of type 1. or type 2. If you need to do that you can add an extra output port to the multifunction_node.
typedef multifunction_node<my_or_node_type::output_type, tuple<std::vector<double>, int> > my_mf_node_type;
struct mf_node_body {
void operator()(const my_or_node_type::output_type &in, my_mf_node_type::output_ports_type &op) {
switch(in.indx) {
case 0: {
// do the operation for the first input (the std::vector) The vector will be in
// get<0>(in.result). Remember you are copying vectors here, so if you have big
// vectors you will probably want to do some buffer management on your own and
// pass refs to the vector instead.
}
break;
case 1: {
// do the operation signaled by the second input (the bool.) The value of the
// input is in get<1>(in.result).
}
break;
}
}
};
main() {
graph g;
my_or_node_type multi_in(g);
my_mf_node_type multi_out(g, unlimited, mf_node_body());
// if the vector-producing node is called vpn, you attach it to the 0-th input of the or_node with
// make_edge(vpn, input_port<0>(multi_in));
//
// the bool-producing node bn can be attached similarly:
// make_edge(bn, input_port<1>(multi_in);
//
// attach the multi-in to the multi-out:
// make_edge(multi_in, multi_out);
//
// attach the vector consumer node vcn
// make_edge(output_port<0>(multi_out), vcn);
//
// attach the integer output to the int consuming node icn
// make_edge(output_port<1>(multi_out), icn);
//
// start up the graph and make sure to do a wait_for_all() at the end.
}
Remember that the multifunction_node body is invoked in parallel, so the work it does should not have race conditions (unless you want race conditions for some reason.) You can make the node body execute serially by constructing it with serial instead of unlimited. And the only way to ensure you can safely destroy the graph is to make sure no tasks are executing any of the nodes. The best way to do this is to do a g.wait_for_all().
Regards,
Chris
P.S. - one addendum. If the multifunction_node is defined serial, it will have an input buffer unless you explicitly exclude it. This may change the behavior of your graph if you are not expecting the buffer to be there.