之前的文章中介绍过蓝牙的速度和踏频协议,在那篇文章中也顺便介绍了BLE的一些小名词.这一篇文章就来说说炫轮App 3.0中的测速模块是怎么构成的吧.

Context

炫轮App可以获取到哪些传感器的数据呢?

  1. 炫轮车灯自身的码表数据
  2. 炫轮踏频器
  3. 满足公有踏频速度协议的传感器
  4. GPS

他们的数据是些什么?

1.炫轮车灯的数据

炫轮车灯会通过蓝牙得到每转一圈需要的时间

2.炫轮踏频器

这个产品不测速,所以先不多说~

3.满足公有协议的踏频速度传感器

通过蓝牙得到在第x秒转了y圈的信息

4.GPS

GPS数据本身就携带了速度信息,只不过,如果GPS信号不强,那这个数据就会不精准

再来个附加功能

大多数的骑行App的一次运动运动时间是手动点击开始,暂停,保存来记录的.这样不是很难过嘛?我想要个自动开始,自动暂停的码表!

不用往下翻,我没写~~这只是打个广告

Structure

所以和速度有关的传感器目前为止大概是那么3类: 炫轮车灯,满足公有协议的速度计,GPS

既然,GPS那么不稳定,干脆砍掉算了.

所以问题就变成了,如何根据炫轮车灯和速度计来计算出较为准确地速度.


Structure-Context

App 可以连接两个炫轮车灯,一个速度计

码表模块是和界面分离的,把他当做服务来处理(这里我写了一个单例),这个类可以收数据,也可以被获取数据.收到的自然是解析后的炫轮数据和速度计的数据,提供获取接口的是多种单位下的:当前速度,平均速度,总路程,总运动时间,(当然还有踏频和心率,只是这里不用,所以就不说了)


全局变量

计时器1枚,记录炫轮数据的数组2枚,记录速度计的数据的数组1枚.

其他的变量这篇文章用不到,就当他不存在了

-(void)updateXuanwheelSpeed:(NSTimeInterval)timeinterval ForPosition:(int)position
{
    switch (position) {
        case 0:
        {
            //########
            [xuanWheelTemporaryList addObject:@(timeinterval)];
            xuanwheelRevolution1++;
            //########
            break;
        }
        case 1:
        {
            //########
            [xuanWheelTemporaryList addObject:@(timeinterval)];
            xuanwheelRevolution2++;
            //########
            break;
        }
        default:
            break;
    }    
}

这是处理炫轮数据的方法,把一圈的时间间隔记录下来,分开写是因为要分别记录两个轮子转的圈数,帮助计算距离.

-(void)updateSpeeder:(Float32)frequency
{
    //########
    [publicTemporaryList addObject:@(frequency)];
}

公有协议的数据,我在这之前就一经计算好了转一圈的频率.已知在第X1秒转了Y1圈,在X2秒转了Y2圈.那么频率就是(X1-X2)/(Y1-Y2)

记录完毕数据,就该计算相关信息了

Calculate

-(void)optimizeSpeed
{
    if (######) {
        //....
    }else
    {
        //#####
        //Reason1:只有一组数据,还怎么计算平均速度;Reason2:#####
        if (publicTemporaryList.count>1||xuanWheelTemporaryList.count>1) {
            int count=0;
            //time用来存放这1秒内平均的转过1圈需要的时间
            NSTimeInterval time=0;
            for(NSNumber *item in publicTemporaryList)
            {
                //这里来计算公有协议的速度信息
                if (item.floatValue>5) {
                    //这么慢还是忽略吧
                    continue;
                }
                if (item.floatValue<=0) {
                    //谁解析的数据!!
                    continue;
                }
                time+=1.f/item.floatValue;
                count++;
            }
            if (publicTemporaryList.count>0) {
                if (publicTemporaryList.count>1) {
                    [publicTemporaryList removeObjectsInRange:NSMakeRange(0, publicTemporaryList.count-1)];
                }else
                {
                    [publicTemporaryList removeAllObjects];
                }
                //算完删光,留下一组数据,为下一秒做帮助,防止突变
            }
            for(NSNumber *item in xuanWheelTemporaryList)
            {
                //这里来计算炫轮的速度信息
                if (item.floatValue>5) {
                    continue;
                }
                if (item.floatValue<=0) {
                    continue;
                }
                time+=item.floatValue;
                count++;
            }
            if (xuanWheelTemporaryList.count>0) {
                if (xuanWheelTemporaryList.count>1) {
                    [xuanWheelTemporaryList removeObjectsInRange:NSMakeRange(0, xuanWheelTemporaryList.count-1)];
                }else
                {
                    [xuanWheelTemporaryList removeAllObjects];
                }
                //Again,留一组数据来备用
            }
            if (count==0||time==0) {
                currentS=0;
            }else
                currentS=[PublicResource sharedObject].roundLength*count/time*3600;
                //这个就是这1秒的速度了咯
        }else
        {
            //#####
        }
    }
//最新的最高速度
    if (currentS>max_inner_speed) {
        max_inner_speed=currentS;
    }
//防止速度突变
    if (currentS>lastSpeed+30) {
        lastSpeed=currentS;
        currentS=0;
    }
//强制限速
    if (currentS>80) {
        currentS=80;
    }
}

差不多,速度就是这么计算的,在实际测试中,感觉还是满准确地~