寫在前面:這。。大概算是一篇技術貼吧。。
需要准備的東西:夜神模擬器(@夜神 請准備好廣告費,過兩天我讓海綿寶寶去收)https://www.yeshen.com/
陽光體育服務平台app(這個**軟件真對得起它的評分):鏈接(也可以去公眾號下載): https://share.weiyun.com/5NeBevD (密碼:D2Rb)
以及。。請給我個贊安慰安慰我浪費在這破軟件上的時間。👍
進入主題——足不出戶刷長跑
既然是學習,先來講講原理吧。想要完成一次長跑,需要達成以下幾點:
-
- 跑滿5個規定的點
- 跑滿規定的路程(男生2km)
- 速度在規定范圍內(男生要在2m/s~4m/s)超過最大規定速度或者低於最小規定速度,都視為無效成績
上面三點是硬性條件,不滿足就無法完成長跑。所以一些root后的位置模擬app、以及現在還有一些不用root手機的虛擬定位app都可以完成這個要求,而且它們的搖桿用起來比模擬器用鼠標點舒服多了(小聲逼逼)。
但是這樣會有一個問題,就是完成長跑后會發現2km,步數為10步。。(飛呢???)
是的,這個破app還會計步。雖然不是硬性條件,但是成績看起來總歸有那么些不舒服。
計步app原理
(以下關於計步原理,主要是來自這篇文章http://www.sohu.com/a/190966257_468626)
電子計步器通常是內置一個加速度傳感器(Accelerometer)和一個運算單元(MCU),通過加速度傳感器感應用戶的加速度變化,然后通過MCU來估算行走的步數。電子式計步器通常采用三軸加速度傳感器,可以感應用戶在三維方向上的運動,且內置較為復雜的計步算法。
目前智能手機和某些非智能手機都內置了加速度傳感器,只需要增加相應的軟件即可實現計步,無需增加硬件成本。智能手表,智能手環類產品也都內置加速度傳感器和計步算法,方便用戶監控自己的運動量。
以放置在手腕處的加速度傳感器(手環、手機其實一樣)為例。用戶在水平步行運動中,手腕處的加速度會收到重力加速度和甩手加速度的雙重影響。如下圖所示,紅色箭頭表示重力加速度,綠色箭頭表示甩手加速度。
在步行過程中,重力加速度始終垂直與大地,甩手動作帶來的加速度呈周期性變化。 反映到圖表中,可以看到,在步行運動中,垂直和前進產生的加速度與時間大致為一個周期性信號。
通過對軌跡的峰值進行檢測計算和加速度閥值決策,即可實時計算用戶運動的步數,還可依此進一步估算用戶步行距離。
計步算法:
計步算法可以分為四大類,一是峰值檢測算法,二是變換域算法,三是濾波算法,四是模式識別算法。根據所設計的計步器在人體上布放的位置不同,如腕部、腰部、鞋底等,可以選擇不同的計步算法。
峰值檢測類算法原理簡單,易於實現,應用較為廣泛。這里簡單介紹峰值檢測類算法。用戶在運動中,可能把設備放置於口袋或者包中,亦或拿在手中。所以設備的放置方向不確定。那么首先,我們通過計算三個加速度的矢量長度,可以獲得一條步行運動的正弦曲線軌跡。
第二步就是峰值檢測,我們記錄了上次矢量長度和運動方向,通過矢量長度的變化,可以判斷當前加速度的方向,並和上一次保存的加速度方向進行比較。如果是相反的,即是剛過峰值狀態,則進入計步邏輯進行計步,否則就舍棄這段。通過對峰值次數的累加,那我們就可得計算得到用戶步行的步數。
最后,就是去噪音(干擾)。手機或智能手表等手持設備會有一些低幅度和快速的抽動狀態,即我們俗稱的手抖,或者某個用戶想通過短時快速反復搖動設備來模擬人走路,這些干擾數據如果不剔除,會影響記步的准確值,對於這種干擾,我們可以通過給檢測加上閥值和步頻判斷來過濾。目前人類最快的跑步頻率為5HZ(當然不排除人類借助其它設備跑步頻率超過這個頻率),也就是說相鄰兩步的時間間隔的至少大於0.2秒,如圖中的計步時間,若兩次計步之間的時間間隔小於0.2秒,則不計步。這樣我們就過濾了高頻噪聲,即步頻過快的情況。同時我們通過和上次加速度大小進行比較,設置一定的閥值Threshold來判斷運動是否屬於有效(如圖中的綠線),有效運動才可進行記步。
如果已知步行和跑步的步數,那么再通過人體身高,體重及性別就可以大致知道此人的步長,改進后即可變成一個測距離及測速計。通過三軸加速度傳感器,我們可以知道用戶的運動狀態。除了計步,還可以利用加速度傳感器與陀螺儀及磁傳感器融合進行步行航跡推算。
所以從原理上出發——計步來源於搖手機,但是手搖太累,所以使用夜神模擬器錄制”搖一搖“操作,然后加速重復操作(雖然有些被過濾掉,但至少看起來數據不再那么假)。
進入正題——開始操作
本來想好寫一大堆話的,等到打算寫了卻發現沒啥好寫的。先看視頻吧,把一些操作寫到了視頻里。視頻是拼接的,第一次錄的時候,差點么把我手點抽筋。等錄完視頻幫舍友刷跑步的時候又發現了個更舒服點的操作,打算放在視頻之后講。(原本打算一遍錄一遍講解的,不過宿舍里比較吵,所以就打字幕了。小黑的歌和顏一樣好=w=)
https://www.bilibili.com/video/av47516576/
注:
-
- 錄制搖一搖操作時,其他不必要的時間不要太長
- 不要先跑完5個點再去刷滿路程,因為這樣路程一滿2km系統就會自動結束,你就來不及”搖一搖“了。(而且后期可以直接快速定位你所需要的點 俗稱:飛起來)
- 一旦你定位的兩個點距離過遠,瞬時速度就會超過6.5m/s,也就說瞬時速度會變紅,系統會認為你在飛,並且不會把你的這段路程計入總路程(我試過40.5m/s的瞬時速度= =)。
- 在刷路程的時候盡量先把自己的速度提升上去(除了手速快點,下面會講一個優化的方法),這樣可以給你更多時間去獲得步數。
- 在刷步數的時候記得關注你的勻速,跌落最小速度成績就無效了。
看完視頻,感覺步數問題是得到了很好的解決,而且在鏡湖里刷長跑也確實挺爽,但是點來點去也太TM累了。而且有的時候還控制不好距離
然后我發現這個模擬器的虛擬定位可以記住位置!!!
所以我打算找兩個距離差不多的點,然后在這兩個點來回切換(視頻稍后放),頓時省力多了。
我試了一下,憑我電腦的延遲,兩個點相聚11.414788113819023米時,我的速度正好可以達到6.5m/s,而且可以被記入路程。【蜜汁微笑】
那么問題來了:地圖上我只有經緯坐標,怎么計算距離呢?
解:
設兩點A、B的經、緯度分別為(jA,wA)(jB,wB),則半徑為R的球面上兩點間的最短距離(大圓弧)為:
弧AB=R*arccos[sin(wA)sin(wB)+cos(wA)cos(wB)*cos(jA-jB)]
地球是一個近乎標准的橢球體,它的赤道半徑為6378.140千米,極半徑為6356.755千米,平均半徑6371.004千米。如果我們假設地球是一個完美的球體,那么它的半徑就是地球的平均半徑,記為R。如果以0度經線為基准,那么根據地球表面任意兩點的經緯度就可以計算出這兩點間的地表距離(這里忽略地球表面地形對計算帶來的誤差,僅僅是理論上的估算值)。設第一點A的經緯度為(LonA, LatA),第二點B的經緯度為(LonB, LatB),按照0度經線的基准,東經取經度的正值(Longitude),西經取經度負值(-Longitude),北緯取90-緯度值(90-Latitude),南緯取90+緯度值(90+Latitude),則經過上述處理過后的兩點被計為(MLonA, MLatA)和(MLonB, MLatB)。那么根據三角推導,可以得到計算兩點距離的如下公式:
C = sin(MLatA)*sin(MLatB)*cos(MLonA-MLonB) + cos(MLatA)*cos(MLatB) Distance = R*Arccos(C)*Pi/180
這里,R和Distance單位是相同,如果是采用6371.004千米作為半徑,那么Distance就是千米為單位。
如果僅對經度作正負的處理,而不對緯度作90-Latitude(假設都是北半球,南半球只有澳洲具有應用意義)的處理,那么公式將是:
C = sin(LatA)*sin(LatB) + cos(LatA)*cos(LatB)*cos(MLonA-MLonB) Distance = R*Arccos(C)*Pi/180
以上通過簡單的三角變換就可以推出。
如果三角函數的輸入和輸出都采用弧度值,那么公式還可以寫作:
C = sin(LatA*Pi/180)*sin(LatB*Pi/180) + cos(LatA*Pi/180)*cos(LatB*Pi/180)*cos((MLonA-MLonB)*Pi/180) Distance = R*Arccos(C)*Pi/180
附:源代碼
/** * google maps的腳本里代碼 */ private const double EARTH_RADIUS = 6378.137; private static double rad(double d) { return d * Math.PI / 180.0; } /** * 根據兩點間經緯度坐標(double值),計算兩點間距離,單位為米 */ public static double GetDistance(double lat1, double lng1, double lat2, double lng2) { double radLat1 = rad(lat1); double radLat2 = rad(lat2); double a = radLat1 - radLat2; double b = rad(lng1) - rad(lng2); double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a/2),2) + Math.Cos(radLat1)*Math.Cos(radLat2)*Math.Pow(Math.Sin(b/2),2))); s = s * EARTH_RADIUS; s = Math.Round(s * 10000) / 10000; return s; }
可以自己去選點然后計算距離鴨~~~~~~
然后我給兩個檀香旁邊的點吧:
A(32.092334,118.64402) B(32.092383,118.64392)
距離=0.011414788113819024 km =11.414788113819023 m
放視頻:https://www.bilibili.com/video/av47516576/?p=2
開掛一時爽,一直開掛一直爽啊。(這一點都不蘇維埃。)
嘗試了這些,最后覺得還不如去跑一圈來的舒服點。(不是大家不喜歡鍛煉,只是不喜歡這種形式罷了。。)
我可沒不讓大家陽光長跑啊!!!!
僅供學習交流,因使用本工具而造成的一切不良后果由使用者自行承擔,與作者無關(¬︿̫̿¬☆)
為了我的繼續運營,請大家繼續一如既往地表面支持陽光長跑。。
其實吧,有的時候網絡環境好的話,飛起來也是會被記入系統的。
而且,就步數這個有些手機的傳感器確實不那么靈敏,所以說步數嚴格來說不能作為一個評判標准。← ←。懂我幾個意思吧。