问题分析

连接购物车

出发前购物机器人是车头与购物车的车头呈垂直的,因此,为了拿到购物车,我们就需要前进半格,然后左转,并且后退一格,最后再去连接购物车

购物机器人完成前进,左转,后退的动作之后就是现在这个位置啦,接下来我们就要借助HC-SR04超声波传感器来进行定位连接购物车了

后面的超声波传感器的位置

准备抓取货物

因为我们需要抓取货物,因此购物机器人是前端光电传感器压白色循迹线拍照停车的,但是我们转圈一定是需要在白线交叉点上转圈的,因此在拍照图像识别到需要抓取的货物之后,购物机器人匀速前进半格,使其走到白线交叉点上,然后左转,使得购物机器人朝向货柜,最后再走进去拿货物即可,那么再朝向货柜之后走进去这个动作的终止条件是什么呢?自然也是用到了HC-SR04超声波传感器

前面的HC-SR04超声波传感器的位置

超声波传感器介绍

我用的是下面这款HC-SR04的超声波传感器,这款超声波传感器的优点就是,他可以直接通过按键设定特定距离,当超声波传感器感知到其距离障碍物的距离小于该设定的特定距离之后,其特有的OUT引脚便会输出高电平,反之,在正常状况下OUT引脚输出的均为低电平。

连接购物车的方法

当底盘子系统接收到树莓派发送的连接购物车的指令之后,底盘子系统会开始匀速且以较低速度开始后退

#define B_BACK_SPEED 1000
#define B_LOW_SPEED  600
if(MOV_STA == BACK || MOV_STA == B_BACK_HALF){
    if(speed < B_BACK_SPEED){
        speed += add_val;
    }
}
else if(MOV_STA == LEFT){
    if(speed < B_LOW_SPEED){//走进去拿购物车
        speed += add_val;
    }
}

这段代码是在MODE_B里面做处理的,需要做特殊说明的是,因为可用命令不足,因此用MODE_B里面的LEFT来实现了连接购物车的功能,所以在MODE_B模式下的LEFT就是连接购物车的功能。
回到正题,那么后退到什么时候时候机器人会停止运动呢?那就是机器人后面的光电传感器感知到特定距离了,OUT引脚输出高电平了,那么这个特定距离是如何测试得出的呢?
方案很简单,就是先把机器人和购物车连接在一个合适的位置,此时光电传感器感知到的距离就是停车距离,那么只要在这个时候按下光电传感器上的记录按钮即可记录下此时特定停车距离。
因此在购物机器人后退时,当光电传感器感知到障碍物已经在特定距离之内了之后,就会执行停车的命令,这里的障碍物指的就是购物车背靠的货架
我在购物车底下粘了一块钢板,当机器人停车之后,再打开电磁继电器就可以吸住购物车底下的钢板了,从而完成了购物机器人连接购物车的任务。

#define IS_GETCAR    HAL_GPIO_ReadPin(HCSR04_BACK_PORT,HCSR04_BACK)
#define ELEC_ON     HAL_GPIO_WritePin(ELEC_SWITCH_GPIO_Port, ELEC_SWITCH, GPIO_PIN_SET);
if(MOV_MODE == MODE_B){
    switch (MOV_STA){
        case LEFT:
            if(IS_GETCAR){
                ELEC_ON;
                stop_task();
            }
            break;

    }
}

连接效果图

靠近货架拿货物的方法

这个方法和连接车的方法是相同的,但是速度控制上略有不同。因为在靠近货架拿货物之前,购物机器人还要过一个十字叉,因此为了减少购物机器人行进的时间,我就放弃了匀速,低速运动的策略,改为先加速后减速的方法,实践证明这个方案也是能保证稳定的。
那么为什么连接购物车的时候要匀速,低速呢?这是因为购物机器人要钻到购物车的下面去,稍微偏一点都有可能会撞到购物车的框子,因此,匀速,低速最能保证购物机器人姿态的稳定

#define IS_GETWALL    HAL_GPIO_ReadPin(HCSR04_GPIO_Port,HCSR04)
    case GET_WALL:
        if (IS_GETWALL == GPIO_PIN_SET){
            stop_task();
        }
        break;

    if(MOV_STA==GET_WALL){
        //如果引脚为高电平则停车
        switch(cut_spd){
            case 0:                
                if ((uart7Rx[1]&0xff)==0xff){
                    if(speed < GETWALL_SPEED_LOW){
                        speed = GETWALL_SPEED_LOW;
                    }else{
                        cut_spd=1;
                    }
                }else if(speed < GETWALL_SPEED_HIGH){                                                                //加速过程
                    speed += add_val;
                }
                break;
            case 1:
                if((speed>GETWALL_SPEED_LOW)){
                    speed=GETWALL_SPEED_LOW;
                }
                break;
        }
    }

效果图


(づ ̄3 ̄)づ╭❤~一键三连,这次一定(๑•̀ㅂ•́)و✧