Get time between to peaks of a signal - ios

all.
I need help, I have a signal like this one
/\
/\ / \
/ \ /\ / \
0 ---------------------------------------
/ \ / \ / \ /
\/ \ / \ /
\/ \/
and I need to detect all peaks (negative and positive). all values are float and I get all 66ms. I want to know time between two peaks. I need help to achieve it, I think I need to store all values in an array with timestamp from last peak, any one have best approach to do it ?
Thanks.

To discover a peak you might want to discover a change in direction.
You would not necessarily have to store the values in an array.
Pseudocode:
//every frame:
frameIncrement++;
currentDir = currentVal - prevVal
if( (prevDir < 0 && currentDir > 0) || (prevDir > 0 && currentDir < 0)) {
//change in direction!
time = frameIncrement * 66
frameIncrement = 0
}
prevDir = currentDir
prevVal = currentVal
Hope this helps!

Related

Fortran: matrix from symbolic functions

I need to transform a set of symbolic equations defining relations between \vec(a) = (a,b,c) and \vec(x) = (x,y), e.g.
a = 1./2 * x
b = -1./2 * x
c = 1./2 * y
into a matrix form so that I get the matrix A, when I write \vec(a) = A * \vec(x):
/ a \ / 1./2 0 \ / x \
| b | = | -1./2 0 | * \ y /
\ c / \ 0 1./2 /
Now the problem is, that the whole things needs to be in Fortran: reading the equations and transforming them to the matrix A.
I have found the module fparser (https://www.sourceforge.net/projects/fparser/) to evaluate symbolic math expressions, but I could need some help figuring out how to most efficiently build these matrices without doing too much string parsing...
An approach (workaround?) in 100% pure Fortran might be...
! calc.f90
program main
implicit none
real avec( 3 ), xvec( 2 ), A( 3, 2 )
integer i
do i = 1, size(xvec)
xvec = 0 ; xvec(i) = 1.0
call calc()
A(:,i) = avec
enddo
do i = 1, size(avec)
print *, A(i,:)
enddo
contains
subroutine calc()
real a,b,c, x,y
x = xvec(1)
y = xvec(2)
include 'eq.inc'
avec = [a,b,c]
end subroutine
end
eq.inc:
a = 1./2 * x
b = -1./2 * x
c = 1./2 * y
$ gfortran calc.f90 && ./a.out
0.500000000 0.00000000
-0.500000000 -0.00000000
0.00000000 0.500000000
Although it's long ago, I want to post what helped me solving the issue:
I used fparser (http://fparser.sourceforge.net/).

Tcl Tk double click binding is blocked by another binding

I work with tcl 8.6
I've got two tablelists (by Nehmeti):
set pfd(frMain) [frame $fr.frMain]
set pfd(bottomFr) [frame $pfd(frMain).bfr]
set pfd(panWin) [panedwindow $pfd(bottomFr).pw -showhandle 1 -orient vertical -sashpad 0 -sashrelief raised -sashwidth 2]
set pfd(frKlaffNeupkt) [frame $pfd(panWin).frKlaffNeupkt]
pack $pfd(frMesswerte) -anchor nw -expand 0 -fill both
pack $pfd(frKlaffNeupkt) -anchor nw -expand 0 -fill both
pack $pfd(panWin) -anchor nw -expand 1 -fill both
$pfd(panWin) add $pfd(frMesswerte) $pfd(frKlaffNeupkt)
set pfd(tali_mw) [tablelist::tablelist $pfd(frMesswerte).li.tali_mw \
-columns {0 "oid" l \
0 "status" l \
0 "art" l \
0 "sollTyp" l \
0 "Nr" l \
0 "Typ" l \
0 "Gst" l \
0 "Hz" r \
0 "V" r \
0 "S" r \
0 "Q" r \
0 "L" r \
0 "AK" l\
0 "LSEX" l \
0 "lfdNrGes" l}\
-exportselection 0 \
-labelbackground #EEEEEE \
-background white \
-labelfont $tableheadfont\
-font $tableinhfont\
-stretch 12\
-selectbackground $vmVConfig::setVar(activeBG) \
-selectforeground $vmVConfig::setVar(activeFG) \
-selectmode single\
-borderwidth 1 \
-labelborderwidth 1 \
-selectborderwidth 0 \
-tooltipaddcommand [::itcl::code $this tooltipAddCmd] \
-tooltipdelcommand [::itcl::code $this tooltipDelCmd] \
-xscrollcommand [list vmTkTools::configSB "h" $pfd(mw_scrx)]\
-yscrollcommand [list vmTkTools::configSB "v" $pfd(mw_scry)]]
set pfd(noteb) [iwidgets::notebook $pfd(frKlaffNeupkt).noteb]
pack $pfd(noteb) -anchor nw -expand 1 -fill both
set pfd(frKlaffungen) [$pfd(noteb) add -label Klaffungen]
set pfd(tali_klaff) [tablelist::tablelist $pfd(frKlaffungen).li.tali_klaff \
-columns {0 "oid" l 0 "Nr" l 0 "dX" r 0 "dY" r 0 "GwX" r 0 "GwY" r 0 "Rdz" r 0 "lfdNrGes" r}\
-exportselection 0 \
-labelbackground #EEEEEE \
-background white \
-labelfont $tableheadfont\
-font $tableinhfont\
-stretch 7\
-selectbackground $vmVConfig::setVar(activeBG) \
-selectforeground $vmVConfig::setVar(activeFG) \
-selectmode single\
-labelrelief groove \
-borderwidth 1 \
-labelborderwidth 1 \
-selectborderwidth 0 \
-xscrollcommand [list vmTkTools::configSB "h" $pfd(klaff_scrx)]\
-yscrollcommand [list vmTkTools::configSB "v" $pfd(klaff_scry)]]
Both tablelist have Bindings:
set body [$pfd(tali_mw) bodypath]
bind $body <Button-1> +[::itcl::code $this klickZeile %x %y %W]
bind $body <Double-1> +[::itcl::code $this doubleKlickMesswerte %x %y %W]
set body [$pfd(tali_klaff) bodypath]
bind $body <Button-1> [::itcl::code $this klickZeile %x %y %W]
The method klickZeile looks like this
itcl::body vmMaskHelmert::klickZeile {x y W} {
puts "klickZeile"
delCommonKreuz
foreach {pfad xC yC} [tablelist::convEventFields $W $x $y] {}
set row [$pfad containing $yC]
if {$row == -1} {
set row end
}
if {[string first "tali_mw" $W] != -1} {
# select the row
$pfd(tali_mw) activate $row
$pfd(tali_mw) selection clear 0 end
$pfd(tali_mw) selection set $row $row
anzeigePpMp
} else {
$pfd(tali_klaff) activate $row
$pfd(tali_klaff) selection clear 0 end
$pfd(tali_klaff) selection set $row $row
anzeigePpMp4Klaff
}
return
}
It seems, that the method klickZeile blocks my double click binding, the method doubleKlickMesswerte is not being called.
In klickZeile two corresponding rows in both tablelists are selected.
I tried to comment out the two blocks with "activate $row, selection clear 0 end and selection set $row $row". In that case, doubleKlickMesswerte is being called but unfortunately the method klickZeile doesn't work correctly. It seems that in that case the method selects the corresponding row for the row selected before.
So I've got two questions:
How can I prevent the method klickZeile from blocking the double click binding?
Or, if there is no way for this, what can I do, to make the method "klickZeile" work correctly without extra selection and activation?
Thanks for your help!
Mouse click events (at least single/double/triple) without modifiers (like Control) will all trigger when a bind to triple is set up and the user triple-clicks on the target element. The GUI cannot predict that another click is coming. It has to dispatch the single-click event first, followed by the double, then the triple.
Your best alternative is to use a modifier, such as a , because this is unique and does not depend on sequence, as long as the Control button is pressed first ;)
proc doClick { widget } {
puts "You clicked [$widget cget -text]"
}
proc doControlClick { widget } {
puts "You control-clicked [$widget cget -text]"
}
set label_1 [label .l1 -text "This is label 1"]
pack $label_1 -side top -fill both
bind $label_1 <Control-Button-1> { doControlClick %W }
bind $label_1 <Button-1> { doClick %W }

A* only works in certain cases

My a* path finding algorithm only works for certain cases but I don't understand why. Every node in my grid is walkable so in theory every path should work. I believe the error is in this line:
PathFindingNode *neighbor = NULL;
if ((y > 0 && x > 0) && (y < gridY - 1 && x < gridX - 1))
neighbor = [[grid objectAtIndex:x + dx] objectAtIndex:y +dy];
In function -(void)addNeighbors:, the line
if ((y > 0 && x > 0) && (y < gridY - 1 && x < gridX - 1))
neighbor = [[grid objectAtIndex:x + dx] objectAtIndex:y +dy];
has bug because if curNode is on boundary, it does not add neighbors to the queue. So that the algorithm will never reach endNode in the four corners (i.e. [0,0], [gridX-1,0], [0,gridY-1], [gridX-1,gridY-1]).

How to convert Wifi signal strength from Quality (percent) to RSSI (dBm)?

How should I convert Wifi signal strength from a Quality in percentage, usually 0% to 100% into an RSSI value, usually a negative dBm number (i.e. -96db)?
Wifi Signal Strength Percentage to RSSI dBm
Microsoft defines Wifi signal quality in their WLAN_ASSOCIATION_ATTRIBUTES structure as follows:
wlanSignalQuality:
A percentage value that represents the signal quality of the network.
WLAN_SIGNAL_QUALITY is of type ULONG. This member contains a value
between 0 and 100. A value of 0 implies an actual RSSI signal strength
of -100 dbm. A value of 100 implies an actual RSSI signal strength of
-50 dbm. You can calculate the RSSI signal strength value for
wlanSignalQuality values between 1 and 99 using linear interpolation.
RSSI (or "Radio (Received) Signal Strength Indicator") are in units of 'dB' (decibel) or the similar 'dBm' (dB per milliwatt) (See dB vs. dBm) in which the smaller magnitude negative numbers have the highest signal strength, or quality.
Therefore, the conversion between quality (percentage) and dBm is as follows:
quality = 2 * (dBm + 100) where dBm: [-100 to -50]
dBm = (quality / 2) - 100 where quality: [0 to 100]
Pseudo Code (with example clamping):
// dBm to Quality:
if(dBm <= -100)
quality = 0;
else if(dBm >= -50)
quality = 100;
else
quality = 2 * (dBm + 100);
// Quality to dBm:
if(quality <= 0)
dBm = -100;
else if(quality >= 100)
dBm = -50;
else
dBm = (quality / 2) - 100;
Note:
Check the definition of Quality that you are using for your calculations carefully. Also check the range of dB (or dBm). The limits may vary.
Examples:
Medium quality: 50% -> -75dBm = (50 / 2) - 100
Low quality: -96dBm -> 8% = 2 * (-96 + 100)
In JS I prefer doing something like:
Math.min(Math.max(2 * (x + 100), 0), 100)
My personal opinion is that it's more elegant way to write it, instead of using if's.
From experience:
Less than -50dB (-40, -30 and -20) = 100% of signal strength
From -51 to -55dB= 90%
From -56 to -62dB=80%
From -63 to -65dB=75%
The below is not good enough for Apple devices
From -66 to 68dB=70%
From -69 to 74dB= 60%
From -75 to 79dB= 50%
From -80 to -83dB=30%
Windows laptops can work fine on -80dB however with slower speeds
Im glad I found this post cause I was looking for a way to convert the dbm to percentage. Using David's post, I wrote up a quick script in python to calculate the quality percentage.
#!/usr/bin/env python3
import os
import platform
system = platform.system()
if system == 'Linux':
cmd = "iwconfig wlan0 | grep Signal | /usr/bin/awk '{print $4}' | /usr/bin/cut -d'=' -f2"
elif system == 'Darwin':
cmd = "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | grep CtlRSSI | awk '{ print $NF; }"
else:
print("Unsupported os: {}".format(system))
dbm = os.popen(cmd).read()
if dbm:
dbm_num = int(dbm)
quality = 2 * (dbm_num + 100)
print("{0} dbm_num = {1}%".format(dbm_num, quality))
else:
print("Wifi router connection signal strength not found")
In order to get the highest wifi quality from where my computer is located, I moved/rotated my antenna until I received the highest quality. To see real time quality, I ran the above script using:
watch -n0.1 "python getwifiquality.py"
I know this may be late but this may help someone in the future.
I took the value of dBm 30-90 for RSSI and correlated it to 100-0 %.
I used the basic linear equation to get the answer.
y = mx + b
We know our x values for dBm as 30 and 90.
We know our y values for % as 100 and 0.
We just need to find the slope. So we can make it linear.
m = 100-0/30-90
= 100/-60
= -5/3
b = y - mx
= 0 + 5/3*90
= 150
Final equation to put in code when you know the RSSI value.
% = 150 - (5/3) * RSSI
Note I did take the RSSI value that is normally negative and multiplied by the absolute value to get positive numbers.
quality = abs(RSSI)
% = 150 - (5/3) * quality
From RSSI vs RSS:
RSSI - Received Signal Strength Indicator
RSS - Received Signal Strength
RSSI is an indicator and RSS is the real value. Ok, now what do you mean by indicator, indicator mean it can be a relative value and RSSI is always a positive value and there is no unit for the RSSI.
We can say RSSI is for common man to understand. RF values are always told in dBm and the values are negative values most of the time. To make it easy for the people to understand these negative values are converted to positive values through scaling.
Say for example, if the maximum signal strength is 0 dBm and minimum is -100 dBm. We can scale it like as explained. We can put 0 dBm and more (RSS) as 100 RSSI (i. e. maximum RSSI) and -100 dBm (or less) as 0 RSSI (minimum RSS).
This is what i have done :
long rssi = WiFi.RSSI();
rssi=-rssi;
int WiFiperct;
if (rssi<27){
WiFiperct =100;
}
else if(rssi>=27&&rssi<33){
WiFiperct=150-(5/2.7)*rssi;
}
else if(rssi>=33&&rssi<36){
WiFiperct=150-(5/3)*rssi;
}
else if(rssi>=36&&rssi<40){
WiFiperct=150-(5/3.3)*rssi;
}
else if(rssi>=40&&rssi<80){
WiFiperct=150-(5/3.5)*rssi;
}
else if(rssi>=80&&rssi<90){
WiFiperct=150-(5/3.4)*rssi;
}
else if(rssi>=90&&rssi<99){
WiFiperct=150-(5/3.3)*rssi;
}
else{
WiFiperct=0;
}
This article is a more detailed explanation of mW, dBm and RSSI
http://madwifi-project.org/attachment/wiki/UserDocs/RSSI/Converting_Signal_Strength.pdf?format=raw
According to it RSSI do not have a unit. It's a value defined in 802.11 standard and calculated by nic card and sent to OS. The nic card vendor should provide a mapping table of dBm-RSSI values.
Sorry for the direct link, but I can not found the original page for the file link.
Mentioned pseudocode will not work all the ranges, the ranges example (-80dBm to 0, and -40dBm to 100).
Generic simple logic to map any range to 0 to 100.
Usage example, for below code ConvertRangeToPercentage(-80,-40,-50)
int ConvertRangeToPercentage (int a_value_map_to_zero, int a_value_map_to_100, int a_value_to_convert)
{
int percentage = 0;
if (a_value_map_to_zero < a_value_map_to_100)
{
if (a_value_to_convert <= a_value_map_to_zero)
{
percentage = 0;
}
else if (a_value_to_convert >= a_value_map_to_100)
{
percentage = 100;
}
else
{
percentage = (a_value_to_convert - a_value_map_to_zero) * 100 / (a_value_map_to_100 - a_value_map_to_zero);
}
}
else if (a_value_map_to_zero > a_value_map_to_100)
{
if (a_value_to_convert >= a_value_map_to_zero)
{
percentage = 0;
}
else if (a_value_to_convert <= a_value_map_to_100)
{
percentage = 100;
}
else
{
percentage = (a_value_to_convert - a_value_map_to_zero) * 100 / (a_value_map_to_100 - a_value_map_to_zero);
}
}
else
{
percentage = 0;
}
return percentage;
}
Ok.. I agree...but why is then:
Quality=29/100 Signal level=-78 dBm
Quality=89/100 Signal level=-55 dBm
Quality=100/100 Signal level=-21 dBm
this does not agree with the formula
percentage=quality/2 - 100.
Also, you can try inverse this Bash function which converts dBm to percentage:
#!/bin/bash
function dbmtoperc { # Convert dBm to percentage (based on https://www.adriangranados.com/blog/dbm-to-percent-conversion)
dbmtoperc_d=$(echo "$1" | tr -d -)
dbmtoperc_r=0
if [[ "$dbmtoperc_d" =~ [0-9]+$ ]]; then
if ((1<=$dbmtoperc_d && $dbmtoperc_d<=20)); then dbmtoperc_r=100
elif ((21<=$dbmtoperc_d && $dbmtoperc_d<=23)); then dbmtoperc_r=99
elif ((24<=$dbmtoperc_d && $dbmtoperc_d<=26)); then dbmtoperc_r=98
elif ((27<=$dbmtoperc_d && $dbmtoperc_d<=28)); then dbmtoperc_r=97
elif ((29<=$dbmtoperc_d && $dbmtoperc_d<=30)); then dbmtoperc_r=96
elif ((31<=$dbmtoperc_d && $dbmtoperc_d<=32)); then dbmtoperc_r=95
elif ((33==$dbmtoperc_d)); then dbmtoperc_r=94
elif ((34<=$dbmtoperc_d && $dbmtoperc_d<=35)); then dbmtoperc_r=93
elif ((36<=$dbmtoperc_d && $dbmtoperc_d<=38)); then dbmtoperc_r=$((92-($dbmtoperc_d-36)))
elif ((39<=$dbmtoperc_d && $dbmtoperc_d<=51)); then dbmtoperc_r=$((90-($dbmtoperc_d-39)))
elif ((52<=$dbmtoperc_d && $dbmtoperc_d<=55)); then dbmtoperc_r=$((76-($dbmtoperc_d-52)))
elif ((56<=$dbmtoperc_d && $dbmtoperc_d<=58)); then dbmtoperc_r=$((71-($dbmtoperc_d-56)))
elif ((59<=$dbmtoperc_d && $dbmtoperc_d<=60)); then dbmtoperc_r=$((67-($dbmtoperc_d-59)))
elif ((61<=$dbmtoperc_d && $dbmtoperc_d<=62)); then dbmtoperc_r=$((64-($dbmtoperc_d-61)))
elif ((63<=$dbmtoperc_d && $dbmtoperc_d<=64)); then dbmtoperc_r=$((61-($dbmtoperc_d-63)))
elif ((65==$dbmtoperc_d)); then dbmtoperc_r=58
elif ((66<=$dbmtoperc_d && $dbmtoperc_d<=67)); then dbmtoperc_r=$((56-($dbmtoperc_d-66)))
elif ((68==$dbmtoperc_d)); then dbmtoperc_r=53
elif ((69==$dbmtoperc_d)); then dbmtoperc_r=51
elif ((70<=$dbmtoperc_d && $dbmtoperc_d<=85)); then dbmtoperc_r=$((50-($dbmtoperc_d-70)*2))
elif ((86<=$dbmtoperc_d && $dbmtoperc_d<=88)); then dbmtoperc_r=$((17-($dbmtoperc_d-86)*2))
elif ((89<=$dbmtoperc_d && $dbmtoperc_d<=91)); then dbmtoperc_r=$((10-($dbmtoperc_d-89)*2))
elif ((92==$dbmtoperc_d)); then dbmtoperc_r=3
elif ((93<=$dbmtoperc_d)); then dbmtoperc_r=1; fi
fi
echo $dbmtoperc_r
}
Usage:
echo $(dbmtoperc -48)% # returns 81%
Airodump RXQ is really usefull in the real world conditions...
"Receive Quality as measured by the percentage of packets (management and data frames) successfully received over the last 10 seconds."
"Its measured over all management and data frames. The received frames contain a sequence number which is added by the sending access point. RXQ = 100 means that all packets were received from the access point in numerical sequence and none were missing. That's the clue, this allows you to read more things out of this value. Lets say you got 100 percent RXQ and all 10 (or whatever the rate) beacons per second coming in. Now all of a sudden the RXQ drops below 90, but you still capture all sent beacons. Thus you know that the AP is sending frames to a client but you can't hear the client nor the AP sending to the client (need to get closer)."

How to solve a Zlib adler32 rolling checksum problem?

I am using adler32 function from zlib to calculate the weak checksum of a chunk of memory x (4096 in length). Everything is fine, but now I would like to perform the rolling checksum if the chunks from different file do not match. However, I am not sure how to write a function to perform that on the value returned by adler32 in zlib. So if the checksum does not match, how do I calculate rolling checksum by using original checksum, x + 1 byte and x + 4096 + 1? Basically trying to build rsync implementation.
Pysync has implemented rolling on top of zlib's Adler32 like this:
_BASE=65521 # largest prime smaller than 65536
_NMAX=5552 # largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
_OFFS=1 # default initial s1 offset
import zlib
class adler32:
def __init__(self,data=''):
value = zlib.adler32(data,_OFFS)
self.s2, self.s1 = (value >> 16) & 0xffff, value & 0xffff
self.count=len(data)
def update(self,data):
value = zlib.adler32(data, (self.s2<<16) | self.s1)
self.s2, self.s1 = (value >> 16) & 0xffff, value & 0xffff
self.count = self.count+len(data)
def rotate(self,x1,xn):
x1,xn=ord(x1),ord(xn)
self.s1=(self.s1 - x1 + xn) % _BASE
self.s2=(self.s2 - self.count*x1 + self.s1 - _OFFS) % _BASE
def digest(self):
return (self.s2<<16) | self.s1
def copy(self):
n=adler32()
n.count,n.s1,n.s2=self.count,self.s1,self.s2
return n
But as Peter stated, rsync does not use Adler32 directly, but a faster variant of it.
Code of the rsync tool is bit hard to read, but checkout librsync. It's a completely separate project and it's much more readable. Take a look at rollsum.c and rollsum.h. There is an efficient implementation of the variant in C macros:
/* the Rollsum struct type*/
typedef struct _Rollsum {
unsigned long count; /* count of bytes included in sum */
unsigned long s1; /* s1 part of sum */
unsigned long s2; /* s2 part of sum */
} Rollsum;
#define ROLLSUM_CHAR_OFFSET 31
#define RollsumInit(sum) { \
(sum)->count=(sum)->s1=(sum)->s2=0; \
}
#define RollsumRotate(sum,out,in) { \
(sum)->s1 += (unsigned char)(in) - (unsigned char)(out); \
(sum)->s2 += (sum)->s1 - (sum)->count*((unsigned char)(out)+ROLLSUM_CHAR_OFFSET); \
}
#define RollsumRollin(sum,c) { \
(sum)->s1 += ((unsigned char)(c)+ROLLSUM_CHAR_OFFSET); \
(sum)->s2 += (sum)->s1; \
(sum)->count++; \
}
#define RollsumRollout(sum,c) { \
(sum)->s1 -= ((unsigned char)(c)+ROLLSUM_CHAR_OFFSET); \
(sum)->s2 -= (sum)->count*((unsigned char)(c)+ROLLSUM_CHAR_OFFSET); \
(sum)->count--; \
}
#define RollsumDigest(sum) (((sum)->s2 << 16) | ((sum)->s1 & 0xffff))

Resources