w494143467 发表于 2021-6-21 22:06

【环境专家之智能手表】Part9:活动状态识别

本帖最后由 w494143467 于 2021-6-27 13:23 编辑

<p><strong>1.介绍</strong></p>

<p>活动状态有很多种,主要有站立、坐、走路、浅睡、深睡、跑步、未佩戴,当然这里的每一个状态的识别都是需要有算法的,对原始数据进行分析,然后去编写算法,当然还有机器学习,刚开始算法根据人的身高和体重(用户自行输入),进行算法匹配,而后面通过采集该用户的各种状态的数据并分析,给出最合适的算法,同时还可以像另一个选手的作品【跑步姿势训练鞋】识别用户走路的姿态,给用户建议,不过这个有一定的难度,这次作品就不做了。</p>

<p><strong>2.状态识别</strong></p>

<p>这次作品主要识别三种姿态,未活动,走路和工作。【未活动】是这个是最好检测,的只要检测三轴的方向是否长时间未改变,那么就可以知道佩戴者处于未活动。如果要识别是睡眠还是未活动,这个需要有进一步的算法,暂时略过。</p>

<p>走路的话,其实也是比较好识别的,人在走路过程中,手是晃动的,那么三轴的方向是变化的,就如同下图1一样,戴着【RSL10-SENSE-GEVK】设备时走出分骚的步伐时的三轴角度变化。</p>

<p class="imagemiddle" style="text-align: center;"></p>

<p style="text-align: center;">图1</p>

<p>加速度驱动就不过多的分析了,拿到三轴的方向数据之后,模拟走路输出的波形如下图2所示。</p>

<p class="imagemiddle" style="text-align: center;"></p>

<p style="text-align: center;">图2</p>

<p>其中蓝色是X轴,红色是Y轴,绿色是Z轴。可以看到红色数据变化最大。</p>

<p>那么正常走路的情况下分析X轴就可以了,其中一个波峰或一个波谷就是一步,那么就可以通过这个特性编写计步检测算法,为了预防晃动导致的计步,会有一个前十步的统计,当走了十步之后才会真正开始计步,当然也会加上这十步,如果一次走路未满十步,则会被判断为晃动,具体的实现的代码如下:</p>

<pre>
<code class="language-cpp">int16_t last_y_org = 0;
int16_t last_y_peak = 0;
uint8_t walk_status = 0;        //0未走路,1走路中
uint32_t step_cnt = 0;                //当前步数
uint8_t step_after = 0;                //前十步统计
uint8_t stap_dif_cnt = 0;        //数值不同
//检测走路
uint8_t activity_walk_detect(int16_t y_org)
{
        if(last_y_org == y_org)
        {
                stap_dif_cnt++;        //数值一直相同
                if(stap_dif_cnt &gt;= 10)
                {
                        stap_dif_cnt = 0;
                        walk_status = 0;//当前未走路
                        step_after = 0;        //前十步清零
                }
                return walk_status;
        }

        last_y_org = y_org;
        if(last_y_peak &gt; 0)                //峰值大于0
        {
                if(last_y_org &lt; 0)                //小于0
                {
                        if(walk_status == 0)
                        {
                                step_after++;
                                if(step_after &gt;= 10)
                                {
                                        step_after = 0;
                                        step_cnt += 10;
                                        walk_status = 1;
                                }
                        }
                        else
                        {
                                step_cnt++;//步数+1
                        }
                        stap_dif_cnt = 0;
                }
                else
                {
                        stap_dif_cnt++;        //数值一直相同
                        if(stap_dif_cnt &gt;= 10)
                        {
                                stap_dif_cnt = 0;
                                walk_status = 0;//当前未走路
                                step_after = 0;        //前十步清零
                        }
                }
        }
        else
        {
                if(last_y_org &gt; 0)                //小于0
                {
                        if(walk_status == 0)
                        {
                                step_after++;
                                if(step_after &gt;= 10)
                                {
                                        step_after = 0;
                                        step_cnt += 10;
                                        walk_status = 1;
                                }
                        }
                        else
                        {
                                step_cnt++;//步数+1
                        }
                        stap_dif_cnt = 0;
                }
                else
                {
                        stap_dif_cnt++;        //数值一直相同
                        if(stap_dif_cnt &gt;= 10)
                        {
                                stap_dif_cnt = 0;
                                walk_status = 0;//当前未走路
                                step_after = 0;        //前十步清零
                        }
                }
        }
        last_y_peak = last_y_org;
        return walk_status;
}</code></pre>

<p>通过上面的算法,对应着刚才的波形数据,实际得出的步数波形如下图3所示:</p>

<p class="imagemiddle" style="text-align: center;"></p>

<p style="text-align: center;">图3</p>

<p>其中蓝色为前十步统计,红色为实际步数,绿色为计步状态,可以看到十步之后,实际步数开始直接加上10步,然后就在稳步增长,可以对比图2和图3查看。</p>

<p>接下来就是工作状态了,由于只有三个状态,所以除了未活动和走路就是工作状态了,这里写的比较简单,当不是走路时且三轴方向有变化,就被当作为工作状态,具体代码如下:</p>

<pre>
<code class="language-cpp">//检测工作
int16_t global_x_org = 0;
int16_t global_y_org = 0;
int16_t global_z_org = 0;
uint8_t no_work_cnt = 10;
//检测工作,只要动就是工作
uint8_t activity_work_detect(int16_t x_org, int16_t y_org, int16_t z_org)
{
        if(abs(global_x_org - x_org) &gt; 100|| abs(global_y_org - y_org) &gt; 100 || abs(global_z_org - z_org) &gt; 100)
        {
                global_x_org = x_org;
                global_y_org = y_org;
                global_z_org = z_org;
                no_work_cnt = 10;
                return 1;
        }
        else
        {
                if(no_work_cnt &gt; 0)
                        no_work_cnt--;
                if(no_work_cnt == 0)
                        return 0;
        }
        return 1;
}</code></pre>

<p>最后就是这代码的整合,然后通过广播发送给矿井外设备了,整合的代码如下:</p>

<pre>
<code class="language-cpp">//传入数据
void activity_update_data(bhy_data_vector_t act_data)
{
        uint8_t ret_value = 0;
        ret_value = activity_walk_detect(act_data.y);
        printf("walk:%d,%d,%d\n", step_after, step_cnt, ret_value);
        if(ret_value &gt; 0)        //在走路中,不检测是否在工作
        {
                now_status = WALK;
                return;
        }
        ret_value = activity_work_detect(act_data.x, act_data.y, act_data.z);
        printf("work:%d,%d\n", no_work_cnt, ret_value);
        if(ret_value &gt; 0)
        {
                now_status = WORK;
                return;
        }
        else
        {
                now_status = NO_ACTIVITY;
        }
}

//获取当前状态
ACTIVITY_STATUS activity_get_status(void)
{
        return now_status;
}</code></pre>

<p><strong>3.总结</strong></p>

<p>活动状态检测其实还有很多状态要识别的,由于时间问题暂时就写了这三个状态,能够简单的识别走路,工作和未活动对于这个作品来说够用了,下一篇写状态灯和模式相关的内容。</p>

dql2016 发表于 2021-6-23 09:10

<p>赞,学习了</p>

sipower 发表于 2021-6-23 16:21

<p>厉害<img height="48" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/wanwan88.gif" width="59" /></p>

<p>那个动画的走姿太骚包啦,哈哈哈</p>

w494143467 发表于 2021-6-23 21:00

sipower 发表于 2021-6-23 16:21
厉害

那个动画的走姿太骚包啦,哈哈哈

<p>哈哈,突然想到的,娱乐一下哈。</p>

soso 发表于 2021-6-24 09:02

<p>我也觉得是,走路的小人屌屌的。</p>

sgf201 发表于 2021-6-24 22:33

<p>给你贡献个小点,人跑步和走路的最大区别 是加速度是不是会出现0值</p>

reayfei 发表于 2021-6-26 15:22

<p>赞</p>
页: [1]
查看完整版本: 【环境专家之智能手表】Part9:活动状态识别