New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bangle.js: more accurate step counter (pedometer) #1846
Comments
@dariosalvi78 @MarcusNordstrom I can do some integration to get your code inside the Bangle.js firmware, but it feels like you're probably best placed to ensure this is all working well. If I sent you both Bangle.js devices, would you be interested in getting everything properly calibrated? Currently we get acceleration data at 12.5 Hz which seems like a decent battery life compromise. Do you think the step counting algorithm could work well with that? It seems currently you're using 100Hz but I think that'd drain our battery too quickly if it was running all the time. |
Hi Gordon, I'm glad that you are interested! The 100Hz is not needed really. Marcus tried with 50Hz and accuracy didn't suffer. 12Hz should work in theory considering people rarely do more than 3 steps/s when running. We have one Bangle here, I have programmed it the Espruino way, but this would probably need flashing the entire firmware: do you have instructions for how to do that? Also instructions about how to setup the toolchain would greatly help. I would love to work on this but my time is limited right now. Marcus did his thesis with me, so I am not sure he would be still interested, but maybe he'd like to volunteer? |
That's great! You can update the actual firmware with https://www.espruino.com/Bangle.js#firmware-updates and for building you can use https://github.com/espruino/Espruino/blob/master/README_Building.md - if you have access to Linux (or WSL under windows) it's pretty easy. However developing this way can be a bit slow - so if for instance there are variables/constants that could be exposed to JS in order to help tuning it more quickly, that'd probably be best. Totally understand on the limited time thing! Honestly any help would be great though. Based on https://github.com/Oxford-step-counter/C-Step-Counter we could do with a bunch of data from walking 150 steps? Perhaps the first thing to do would be for me to make an app that made it easy to record accelerometer data in the CSV format you need, then post up a request on the forum to get as many people contributing CSV files as possible? We can then get a good idea what's needed for that 12.5Hz sample rate, and if everything looks ok, building it in should be pretty easy? |
Hi Gordon, Unfortunately I am busy with a full time job and won't be able to help. Gathering data from your community sounds like a good idea and best of luck to you! |
Before crowd-sourcing the data, I'd start with some tests ourselves. The best idea would be if you could write this app to save data in CSV format (format: timestamp in ms or us, accelX, accelY, accelZ, acceleration must be as they arrive from the accelerometer) and we collect a few files while counting the actual number of steps manually. With these files, I can try to optimise the algorithm offline, on my computer, and I can give you back the optimised code. It's possible that we will not need some of the stages, like interpolation and even filtering givne the low sampling frequency, but we need to test it. If it turns out that accuracy is bad at 12.5Hz, would you be able to increase it, for example, to 25Hz? BTW, happy to continue this conversation over email if it makes sense: dariosalvi78 at gmail |
Just done: https://banglejs.com/apps/#accellog I'd already posted it on the forum a few hours ago so we may get some data from other users anyway - although yes, it would have been better for me/us to do some testing ourselves first :) If we could try getting it working well on your PC first, that'd be a really good way to do a proof of concept, and hopefully it's not too painful for you. Once it's working I can probably get it running on Bangle.js pretty well without wasting too much of your time. Potentially we could raise the sampling frequency if needed, yes - but that has knock on effects on battery life, and I'd probably get a few grumbles from users - so ideally we'd stick with it as-is if possible. I'm hopeful that 12.5 will be ok though. Would you prefer email? GitHub works fine for me - it makes it easier to reference code sometimes. |
that was quick! I am OK with using Github issues, so let's keep it here for now. |
I've collected a few files walking 100 steps. If I plot them I can definitely see the steps inside (you can use this to plot them youserlf). Looks like the low sampling frequency should not affect too much, but I'll need to confirm it! I'll keep you posted... |
Great! There are also some other contributed sets of steps at http://forum.espruino.com/conversations/359542 as well now. I'll take a look at getting the code building in Espruino |
Ok, I integrated it here: https://github.com/espruino/Espruino/tree/step_counting I ran the optimisation tool based on all the data we had available, tried to adjust the low-pass filter for 12.5Hz, and came up with these changes: e269ac7 It runs, but (as you could see from the non-active pedometer widget, or |
I'm working on it, there are a few optimizations to be done and I am also checking if there are any bugs. Question: does the MCU have a coprocessor or would it be better to use the approximated implementation of the SQRT? |
Thanks! Yeah, right now it seems there's at least 5k of RAM used for step counting buffers and it'd be really good to try and reduce that substantially. The MCU does have a 32 bit FPU but I think your integer implementation is likely to be significantly faster than converting to/from floats. |
That's great! Is the interpolation needed since all the samples arrive at exactly the same 12.5Hz period? I just disabled it on my build for Bangle.js |
good news! I've got a working version, see attachment. The new version includes the "best" parameters I have found for my set of experiments. These are: with these set, I get avg abs error of 7% min 0% max 20% on my files and avg 15% min 3% max 52% on community's files. Some fixes and optimisations:
Gotchas:
Further work:
Let me know if this works and if it's slim enough (memory and CPU-wise) for the Bangle! |
Great! I'll give this a go now. It'd be amazing if it were possible to remove the interpolation and buffers - but thanks for dropping the size. I'll see if I can get a figure for the RAM usage with/without the algorithm in. We actually have a power-saving mode for when the accelerometer isn't moving much, so what I'll do is just not feed data into the step counter while we're power saving - which should help with the issue with adaption. |
Ok, so I've pulled this in (zip file attached - espruino_2v08.191_banglejs.zip), and here's what I can tell so far:
So I think for it to be at a stage where it can be merged and it's producing more useful data than the current peak detector it'd probably need what you mention under further work. Would you be happy to look into that? On commercial step counting solutions they 'debounce' steps (https://blog.st.com/pedometer-mems-step-count/) so you only really count once someone has got a steady pace. Is that something the current implementation does? I'd asked the folks in the forum to try different types of walking, including stopping and changing styles - and I guess that would account for why there was so much difficulty actually finding steps in the contributed data. |
The sampling is not very precise even at that frequency, I have noticed some samples being lost completely and the period is sometimes less than 80ms. Nonetheless, interpolation can be removed safely, it doesn't impact the accuracy: just set the flag inside config.h. Also remove filtering, it doesn't bring anything useful. Memory: I am quite surprised! Removing the buffers should help, but I don't expect a huge change. Try adjusting the types, maybe it helps as well. We would need a bit of profiling to understand where the biggest gain would come from, I am not sure how to do that (I'm not a C guru TBH). As for detecting steps out of noise, some more processing can be done either in a preliminary stage, where it simply checks if enough energy is in the signal or with this "debouncing" idea in postprocessing, but I haven't got a ready-made solution for it. I would need to gather some signals and play with them. |
regarding types, here are some suggestions:
I am not sure how time and acceleration are treated internally, but you are probably fine to use int16_t in most places except time |
Thanks - that sounds good. Looks like we can cut things down a lot. I made it so that when the watch is stationary for ~1 minute (or you switch apps) it stops recording and resets/sets the time counter to 0 - so I think 32 bits will do us fine there too. |
Thanks for all these improvements! One thing where I see some more potential are the default settings and the thresholds. I have the effect that I get quite many steps counted while only sitting and doing office work on my computer. I am open to suggestions and will be happy to test a few setups and share my experience. Also, I noticed that it seems to count waaay to many steps when I actually do move. Would it be possible to have some kind of "handicap" so it would divide the measurements e.g. by a factor of 5? I guess the main reason for this is as stated above by you @dariosalvi78 :
|
I think what you might be hitting is what I mentioned at #1846 (comment) - it looks like many commercial step counters have a second part which only passes on steps that occur at regular intervals. I feel like having that filter (even applied to the original Bangle.js step counter that's being used) would probably sort out a significant amount of these issues. I just need to figure out how to do it :) |
I have some ideas, I just need to find the time to work on them. As for overcounting when walking, could you send us some tracks with acceleration and a reference step count? You can count your steps in your head or use another device (like a phone) as a reference. We can try to optimise the parameters based on that. Please be aware that the algo does not distinguish between steps and other types of periodical movement so it'll never be 100% accurate. |
Hello! I have found the time to work a little more on this. Attached an improved version of the algo that skips counting steps when there is no movement. Unrelated: I am using your HR detection algorithm on a mobile phone camera project. It works quite well! |
Great - thanks! Right now I'm trialling a very simple step counting based a bandpass filter and threshold, but I just pulled in your most recent code to the branch (needed a few tweaks as now |
Great to hear about the HR detection... Which one was it? The old autocorrelation one, or the new bandpass one? |
I have a couple of students testing something similar to what you did here. We want to compare it with a peak detector (the same used here for step counting!) and see which one is more accurate. But you say that you have another algorithm? Have you published it somewhere? |
Ahh, nice! I meant this one: https://github.com/espruino/Espruino/blob/master/libs/misc/heartrate.c It's what I'm trying now - literally just a bandpass filter, then a threshold detector, then a median filter on the resulting time periods. We'll see how it works in reality but I feel like it's able to recover more easily from bits of invalid data. |
the problem with thresholding is that it's hard to find the right one! Maybe you can combine it with some of the following ideas:
I'm very curious to see how this evolves! |
Hello @gfwilliams, will this feature be implemented for BangleJS 2 at some point? regards Romek |
Hi - yes, it's been in Bangle.js 2 since the start. If you think it's not accurate, best bet would be to record a bunch of data with the acceleration logger app and then add it to https://github.com/gfwilliams/step-count - we can then tweak the current algorithm to work more accurately. |
Hi, It currently includes 2 algorithms, one of which, as I understand it, is the one included in the official firmware. You are very welcome to contribute with your own data or with a new algorithm! |
Referenced here: http://forum.espruino.com/conversations/345726/#comment15324507
https://github.com/Oxford-step-counter/C-Step-Counter
Might be worth a try including it?
The text was updated successfully, but these errors were encountered: