Can I use maths equations in Grafana Graph Metrics? - grafana

My situation:-
I'm measuring the level in my rain water tanks using a float on an arm, connected to a variable potentiometer, monitored by an Arduino.
As the tank goes down the voltage reading decreases in a sinusoidal way (for a range of pi/2 radians, i.e 90 degrees).
Currently I'm reading the values from an InfluxDB remotely via Grafana, which is just displaying the voltage level. This reading will become more and more inaccurate as the level goes down due to the change in angle as it gets lower.
To fix this I want to add a sin(theta) equation into the Grafana/Graph/Metrics section. But I can not find out if that is possible to do that.
From what I've found it appears it may be beyond Grafana to do that, but I've got my fingers crossed as the only other options will be to try and add something into the InfuxDB (way beyond my knowledge) or add the code directly onto the Arduino, which by the way it's all mounted and attached inside my rain water tanks, is something I'm not keen to do.
If anyone can let me know if it's possible (or not) to do it via Grafana it would be greatly appreciated.
Thanks you.

Q: Can I use maths equations in Grafana Graph Metrics?
A: Short answer no. Grafana is a data visualisation tool for making sense out of a dataset.
The job of a timeseries panel like Graph is to take in a set of timeseries dataset formatted as below, and plot the data point accordingly.
Example dataset:
[
{
"target":"upper_75", // The field being queried for
"datapoints":[
[622,1450754160000], // Metric value as a float , unixtimestamp in milliseconds
[365,1450754220000]
]
},
{
"target":"upper_90",
"datapoints":[
[861,1450754160000],
[767,1450754220000]
]
}
]
InfluxDb do support the Sin mathematical operation but I am not sure whether is that sufficient to you or not. I failed my maths in high school so I'm not sure if sin(theta) == sin() or not.
If the influxdb datasource UI does not support the SIN operation yet, you can actually toggle the "advance query edition" mode to manually build it. See img below.
Also, you can learn more about the influx Mathematical syntax here.
References:
https://github.com/grafana/simple-json-datasource
https://play.grafana.org/d/Zzlfq17mk/influx-table-merge?panelId=2&fullscreen&edit&orgId=1
https://docs.influxdata.com/influxdb/v1.7/query_language/functions/#sin

Related

Can I plot the same subset of many days in grafana

I have an interesting event that happens once a day at (say) 10:00. I would like to plot some data for a small time around then for multiple days to explore the data. Is there an easy way to do this with Grafana?
Rough sketch of what I’d like (but I’m not very picky):
A few things I tried:
Searching on the internet. I think this failed because I don’t know the right words to describe what I want
Assuming this is impossible. The reason I would expect this to be possible is that it seems somewhat common to e.g. want to plot the value of some metric during working hours only. But it also seems like something that mightn’t be needed for a reasonably steady 24/7 operation.
Setting up a dashboard with many panels with appropriate timeshifts. This is a bit fiddly to set up and I think it is hard to change the metric being looked at. It also leaves a lot of empty space and I’m not sure if it is possible to lock the y axis scale to be the same for all the panels
I assume that this isn’t currently supported and therefore I suppose the question is what the best workarounds would be. In particular I’m hoping to optimize for something that is convenient to explore the data rather than somethings that is powerful.
Some alternatives that would likely also be good for me:
Some scheme for weighting the x axis (so I could give time in the gap a weight of 0)
Some way to automatically add discontinuities to the x axis when there is no data
A few more specifics:
Grafana v8.1.8 (52edcff798)
The data is stored in VictoriaMetrics, and queried via a PromQL interface (PromQL is a subset of VictoriaMetrics’ MetricsQL. Currently I can’t make MetricsQL queries but can maybe change to do that if it would help here).

Matlab Simulink: while loop with subtraction

I am hoping somebody here will be able to help me out with my small issue with one of the Simulink/Matlab code. It is quite similar to the problem that I’ve discussed earlier, but a little bit more complicated and now it is more a Simulink issue, rather than a Matlab one.
So I have a turbine which speed is controlled by the gate’s opening, hence the control voltage. By controlling the gate opening I am accelerating the turbine and at some point in time, I need to introduce a saturation effect (since I am testing the code now, it will be done an external signal). This effect won’t change the control voltage, but it affects other components of the system, hence at the same control voltage, the turbine’s speed will go up. But at the same time, I need to keep the speed at the same value as it was before the saturation effect (let’s say it was 320 rpm). To do so I need to decrease the control voltage and should keep doing it until I reach the speed as it was before. There is no need to do it instantly (this approach will be later introduced in hardware), but it will be a nice thing to check the algorithm in these synthetic tests.
In terms of the model, I was planning to use a while loop with the speed requirement “if speed > 320” again, now just to simplify things. To decrease the control voltage I was planning to subtract from the original 50 (% opening) - 0.25 (u2) at first and after that increasing this value by 0.25 until I decrease the speed below 320. I can’t know the exact opening when this requirement will be satisfied, hence I need some kind of algorithm to “track” this voltage.
So it should be something like this:
u2 = 0;
While speed > 320
u2 = u2+0.25
End
u2 is initially zero since we have a predefined initial control voltage. And obviously, when we reach the motor’s speed below 320, I need to keep the latest value of the u2 (and control voltage).
Overall, it is a small code and should be done in Simulink (don’t want to introduce any other Fcn function into the model). I’ve never used while and if blocks in Simulink, but so far I came up with this system. It’s a simplified version of my model, but the control principle is the same.
We are getting the motor speed of 350, compared with 320 (the speed before “saturation), and if our speed after saturation is higher, we need to reduce the control voltage. To trigger the while loop block I’ve decided to use a simple switch. The while block meanwhile is:
Definitely not the best implementation but I was trying a lot of different combinations and without any real success. I am always getting the same error:
Was trying to use a step signal instead of the constant “7” – to model acceleration of the motor, and was getting the same error at the moment of acceleration above 320 threshold. So looks like the approach is almost right but mathematically it fails to find the most suitable solution. I’ve tried to implement a transport delay in the memory part of the while subsystem but was getting errors during compilation all the time.
Are there any obvious (and not so) mistakes? Or maybe from the beginning, I should have chosen another approach… I really hope that somebody will be able to help. Thank you in advance and have a great day.
I do not think that you have used While block correctly.
This is what I have done, I used a "Matlab function" block instead of "While" block as follows,
The function in Matlab function is
function u2=fcn(speed,u2d)
if speed>320
u2=u2d+0.25;
else
u2=u2d;
end
And the results I have got, Scope 1
Scope
Edit
As you prefer a function free model, the following may do the same.

How does the complementary filter work?

I'm trying to combine the data from an accelerometer and a gyroscope to accurately measure the pitch and yaw angles of an object. After researching the complementary filter and attempting to implement it, i have a few questions on how it works.
I've read that the filter "trusts" the gyroscope data if there is a lot of angular movement and that it "trusts" the accelerometer data if the object is stable.
http://www.pieter-jan.com/node/11
In this article the complementary filter is described in this way:
*angle = 0.98(angle + gyrData * dt) + 0.02*(accData)*
To me it, seems as if the gyroscope data is being favoured. In the following image, http://www.pieter-jan.com/images/resize/Complementary_Filter.png , found at the bottom of the page, the filtered data seems to "keep close" to the accelerometer data, even though the gyroscope data has drifted. I don't understand why this occurs when the calculation suggests the gyroscope data is being favoured. I have observed this in other photos as well. During my own testing i needed to "swap" the 0.98 and 0.02, suggesting the accelerometer data is being favoured, to obtain similar results. Am i missing completely misunderstanding how this filter works? Is it normal to "favour" the accelerometer data?
Furthermore when the angle of an object needs to be monitored for a long length of time, doesn't the gyroscope data become useless as the drift is so large, how does the filter compensate?
I Realise where i was going wrong.
I had essentially calculated the angle using only the gyroscope data and used that in the filter. i.e
GyroAngle += d°/s * time_between_cycles
FilteredAngle = 0.98*GyroAngle + 0.02*AccelerometerAngle
Instead i should've been doing this:
FilteredAngle = 0.98*(FilteredAngle + d°/s * time_between_cycles) + 0.02*AccelerometerAngle
Doing this has yielded much better results
I'm trying to do something similar to this. I'm implementing a complementary filter in my Arduino code using an LSM9DS0 sensor (It has a gyro/accelerometer built-in https://www.adafruit.com/product/2021
There's a filter value I have been playing around and a calibration method I'm trying to use but I can't seem to get rid of it 100%. There is always a small deviation from the angle and I can never get a 100% filtered angle with no error.

Getting displacement from accelerometer data with Core Motion

I am developing an augmented reality application that (at the moment) wants to display a simple cube on top of a surface, and be able to move in space (both rotating and displacing) to look at the cube in all the different angles. The problem of calibrating the camera doesn't apply here since I ask the user to place the iPhone on the surface he wants to place the cube on and then press a button to reset the attitude.
To find out the camera rotation is very simple with the Gyroscope and Core Motion. I do it this way:
if (referenceAttitude != nil) {
[attitude multiplyByInverseOfAttitude:referenceAttitude];
}
CMRotationMatrix mat = attitude.rotationMatrix;
GLfloat rotMat[] = {
mat.m11, mat.m21, mat.m31, 0,
mat.m12, mat.m22, mat.m32, 0,
mat.m13, mat.m23, mat.m33, 0,
0, 0, 0, 1
};
glMultMatrixf(rotMat);
This works really well.
More problems arise anyway when I try to find the displacement in space during an acceleration.
The Apple Teapot example with Core Motion just adds the x, y and z values of the acceleration vector to the position vector. This (apart from having not much sense) has the result of returning the object to the original position after an acceleration. (Since the acceleration goes from positive to negative or vice versa).
They did it like this:
translation.x += userAcceleration.x;
translation.y += userAcceleration.y;
translation.z += userAcceleration.z;
What should I do to find out displacement from the acceleration in some istant? (with known time difference). Looking some other answers, it seems like I have to integrate twice to get velocity from acceleration and then position from velocity. But there is no example in code whatsoever, and I don't think that is really necessary. Also, there is the problem that when the iPhone is still on a plane, accelerometer values are not null (there is some noise I think). How much should I filter those values? Am I supposed to filter them at all?
Cool, there are people out there struggling with the same problem so it is worth to spent some time :-)
I agree with westsider's statement as I spent a few weeks of experimenting with different approaches and ended up with poor results. I am sure that there won't be an acceptable solution for either larger distances or slow motions lasting for more than 1 or 2 seconds. If you can live with some restrictions like small distances (< 10 cm) and a given minimum velocity for your motions, then I believe there might be the chance to find a solution - no guarantee at all. If so, it will take you a pretty hard time of research and a lot of frustration, but if you get it, it will be very very cool :-) Maybe you find these hints useful:
First of all to make things easy just look at one axis e.g x but consider both left (-x) and right (+x) to have a representable situation.
Yes you are right, you have to integrate twice to get the position as function of time. And for further processing you should store the first integration's result (== velocity), because you will need it in a later stage for optimisation. Do it very careful because every tiny bug will lead to huge errors after short period of time.
Always bear in mind that even a very small error (e.g. <0.1%) will grow rapidly after doing integration twice. Situation will become even worse after one second if you configure accelerometer with let's say 50 Hz, i.e. 50 ticks are processed and the tiny neglectable error will outrun the "true" value. I would strongly recommend to not rely on trapezoidal rule but to use at least Simpson or a higher degree Newton-Cotes formula.
If you managed this, you will have to keep an eye on setting up the right low pass filtering. I cannot give a general value but as a rule of thumb experimenting with filtering factors between 0.2 and 0.8 will be a good starting point. The right value depends on the business case you need, for instance what kind of game, how fast to react on events, ...
Now you will have a solution which is working pretty good under certain circumstances and within a short period of time. But than after a few seconds you will run into trouble because your object is drifting away. Now you will enter the difficult part of the solution which I failed to handle eventually within the given time scope :-(
One promising approach is to introduce something I call "synthectic forces" or "virtual forces". This is some strategy to react on several bad situations triggering the object to drift away although the device remains fixed (? no native speaker, I mean without moving) in your hands. The most troubling one is a velocity greater than 0 without any acceleration. This is an unavoidable result of error propagation and can be handled by slowing down artificially that means introducing a virtual deceleration even if there is no real counterpart. A very simplified example:
if (vX > 0 && lastAccelerationXTimeStamp > 0.3sec) {
vX *= 0.9;
}
`
You will need a combination of such conditions to tame the beast. A lot of try and error is required to get a feeling for the right way to go and this will be the hard part of the problem.
If you ever managed to crack the code, pleeeease let me know, I am very curious to see if it is possible in general or not :-)
Cheers Kay
When the iPhone 4 was very new, I spent many, many hours trying to get an accurate displacement using accelerometers and gyroscope. There shouldn't have been much concern about incremental drift as device needed only move a couple of meters at most and the data collection typically ran for a few minutes at most. We tried all sorts of approaches and even had help from several Apple engineers. Ultimately, it seemed that the gyroscope wasn't up to the task. It was good for 3D orientation but that was it ... again, according to very knowledgable engineers.
I would love to hear someone contradict this - because the app never really turned out as we had hoped, etc.
I am also trying to get displacement on the iPhone. Instead of using integration I used the basic physics formula of d = .5a * t^2 assuming an initial velocity of 0 (doesn't sound like you can assume initial velocity of 0). So far it seems to work quite well.
My problem is that I'm using the deviceMotion.and the values are not correct. deviceMotion.gravity read near 0. Any ideas? - OK Fixed, apparently deviceMotion.gravity has a x, y, and z values. If you don't specify which you want you get back x (which should be near 0).
Find this question two years later, I just find a AR project on iOS 6 docset named pARk, It provide a proximate displacement capture and calculation using Gyroscope, aka CoreMotion.Framework.
I'm just starting leaning the code.
to be continued...

Whate are the basic concepts for implementing anti-shock and anti-shake algorithms?

I have some animations happening upon fine acceleration detections. But when the user sits in a car or is walking it may get annoying.
Basically, all that stuff has to be disabled automatically as soon as there is too much vibration or shaking. Conceptually, I think that it's very hard to filter those vibrations out , since the "vibration phase" changes permanently. I woul define "unwanted vibration or shocks" as acceleration values that change very fast by an large interval of values, or, an permanently changing accumulated value that does not exceed an specified treshold range in an specified minimum period of time.
I am looking for "proven" concepts, before I start reinventing the wheel for a couple of days.
I don't have any concrete answers for you, but you might want to Google band-pass filters or anti-aliasing filters for some ideas on how to approach this. Basically, if you can identify the frequency range of accelerations that you want to consider real, you can filter out frequencies that fall outside this range.
Before you start doing too much pre-optimization, I think you should implement a low pass filter and see if that does the job. Most iPhone apps effectively use a variation of an LPF to get rid of unwanted accelerometer noise.
You could also go the other way and use a high pass filter. Once you get a certain power level passing through the HPF, stop processing data.