回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页
best-icon

#REMAKE再造 第二轮 SMARS小车巡迹游 简单

头像 幸运阿风 2021.03.14 2173 3

第一轮我们介绍了开源经典作品SMARS小车,从搜集资料,到打印部件,从选择电子器件,到焊接电路,从编写程序,到调试调参,亲手一点点组装,复刻了一个优秀的作品。

https://makelog.dfrobot.com.cn/article-309740.html

我将把这个作品分享给朋友。没有意料到,他们反应竟然很一致,最关注的竟然是外观!"漂亮" "可爱" 还有 "想咬一口"的。身边小圈子更多是各式各样的技术宅,本以为大家更关心功能和创意, 或者直接问成本,找各种角度开怼的,没想到,最终让五湖四海的各路奇人收起分歧统一战线的,是大家对美的追求。

当STEM和STEAM喋喋不休的争论,甚至还有 A-STEM,STEM+A,STREAM 这样的变种也想吵着进入主流的时候,国外这位年轻小哥用作品说明,少了一个A不代表作品便丢了艺术,您多了A,也不至于马上就高雅脱俗了。不要看不起理工男的审美,不要听信只讲理论不实践的专家的话!

扯得有点远,再回来。第二轮的主题是 " 超越经典 " ,我们要对小车进行改装。 SMARS,模块化是非常重要的一个特性,它在设计的时候就充分考虑扩展的要求,可以自由发挥创意,所以各种Mod很多。因为抄袭模仿是创新之母,所以我要去T站找一下灵感。

project-image

看过T站各位大神的佳作,还是被震撼了。叉车铲车,四足的两轮的,还有和Cozmo和OTTO嫁接的,千奇百怪,眼花缭乱。它们有个共同的特征,就是和原版一样,比例协调,优雅美观。超越经典,超越经典,这是最好的例子啊!好在这些作者不知道DF造物记的活动,要不然他们来参赛,我如何相比?

闲话少叙,生活继续。作品一定要交的,如若去做创新的扩展结构,一定要符合原作的风格,不求进步,但终究不能给人家抹黑。虽然我的艺术细胞不多,但自知之明还是有的。所以忌惮着,生怕嘴上喊着超越,脚下却行着苟且退步之路。渐渐陷入迷茫,却在将失信心时,困惑中发现根救命的稻草。

虽然作品的艺术外观我们很难大幅修改,但可以在软件上动一动的。目前网站上多数作品在结构上各种优化,很少有关注程序的。好的,我们从这里入手,做机器人编程中一个也是经典的案例------巡迹。

步骤1 巡迹小车的硬件准备

SMARS作为一个全打印的小车,要搞巡迹是有缺点的。首先最大的缺点是它的履带很硬,摩擦系数小,与硬质地面接触面积还小,这样摩擦力过小,在纠正车体偏移过程中很容易打滑。其次,还是由于履带的原因,小车在行驶过程中,地面灰度传感器相对地面会有上下的起伏。而传感器返回数值和地面距离紧密关联,这都给稳定巡迹带来难度。还有小车空间紧张,供电电压偏低等等缺点,我们一 一克服。

project-image

原版使用9V层叠电池供电,这种电池放电电流太小,不适合电机工作。后来使用AAA*3供电,电压4.5V偏低。我们这里使用3.7V 600mah锂电池,两节串联组成电池组,做成标准平衡充接头,给小车供电。

project-image

使用平衡电量显示器测电压,显示单节3.85V,大概50%电量多一点。

project-image

这里充电使用的是航模用简易平衡充,4.2V截止。

project-image
project-image

修改模型文件,将原来用于固定9V电池的卡槽去除,空间刚好容纳新锂电池组。

project-image

地面灰度传感器我选用的是中鸣的光电传感器,它的性能好,更主要原因是手里很多。

project-image

原版传感器外壳尺寸不合适,使用solidworks重新制作一个。

project-image

仔细观察一下传感器与支架的连接方式,利用材料弹性实现无螺丝拼接,突起和凹陷的圆点可以实现不同角度的定位。这些优秀的设计很多,亲手实践,才能体会到经典的魅力。

project-image
project-image

三个灰度安装完毕,接线过程略去了,线材挺影响美观的,下一版也许我会考虑将线材隐藏起来。比较下两图中灰度传感器的角度不同。另外,白色的履带,使用了TPU材质打印,为了是更软,获得更大的摩擦力。

步骤2 程序部分编写

巡迹算法的依据是地面灰度传感器的返回值。我们这里使用的模拟量传感器,它说识别的地面并不是非黑即白。我们的传感器的底端有两个小灯珠,一个是普通LED,发光照向地面,另一个是光敏器件,捕捉从地面反射回来的光的强弱,转化成电信号。一般巡迹场地使用同种材料,地面图形颜色的深浅(灰度传感器不能识别颜色)决定了光反射强弱。也就是说,通过分析传感器返回的数值,便可知传感器所处地面轨迹线。但需要注意的是,在场地白大黑小(举例,或者白小黑大)传感器在黑白线的交界处返回数值并不是突变的。虽然人眼可视黑白分明,但是传感器眼中,黑白交接处更类似一种渐变的灰度。传感器返回数值的范围大小取决于控制器ADC转化精度,例如UNO板是10bit 0~1023。

我们可以大概估算黑白值的分界线,类似100分的考卷,60分位及格标准,我们可以人为的划分一个标准来区分黑白线。比如 传感器返回范围 0~1023 ,那么可以规定所有大于等于500的值都认为白线,小于500的值认为黑线。在这里,这个500的标准被称为阈值。通过与阈值的比较,地面灰度模拟量转化为数字量。

我们可以通过和阈值比较后的数字量来指挥小车左右偏移来持续前进,这一般是传感器巡迹最基础的课程。但刚才讲过,模拟传感器眼中黑白交界处是一条渐变色,那么我们可以通过增加更多阈值来把黑到白划分出更多等级,从而让小车偏移更加精确顺滑。是的,当划分的点足够多,黑白分的足够细,这就是PID中的P,比例巡线。

以上是巡迹理论基础。实践中要考虑更多因素,例如传感器滤波去抖,电机速度极限锁定等等。还有永无止境的优秀算法。上面算是抛砖引玉吧。

虽然为了巡迹对SMARS做个很多改进,但履带影响,巡迹效果依然一般。此外电机选型失误,减速比有些小,影响效果。简单实验了小中大三种地图,有单传感器模拟量比例巡线,有三传感器数字量巡线。以下为视频。小地图看着速度快一下,大地图看着慢,实际差距没有那么大。

大图2.5m*4m,有直线,曲线,直角弯,锐角弯,虚线,交叉线。 时间所限没有特殊处理,有些地方需要用手帮一下^_^

代码
/* Smars 小车
   巡迹测试
   阿风
   2021.02.13C
*/
void ReadGray()
{
  extern int P1,P2,P3;
  extern int S1,S2,S3;
  P1=analogRead(A5); //读灰度传感器数据
  P2=analogRead(A3);
  P3=analogRead(A4);

  if(P1<300){    //和阈值比较,转化为数字量
    S1=1;
  }
  else{
    S1=0;
  }
  if(P2<300){
    S2=1;
  }
  else{
    S2=0;
  }
  if(P3<150){
    S3=1;
  }
  else{
    S3=0;
  }
}

void go (int a,int b)//-255~255  (MX1508 0,0停止  1,1刹车)left 5~ 4  right 6~ 7 555刹车
{  
  if (a==0){
    digitalWrite(5,0);
    digitalWrite(4,0);
  }
  else{
    if (a==555){          //刹车
      digitalWrite(5,1);
      digitalWrite(4,1);
    }
    else{
      if (a>0){
      analogWrite(5,a);
      digitalWrite(4,0);
      }
      else{
      analogWrite(5,a-255);
      digitalWrite(4,1);
      }
    }
  }
  if (b==0){
    digitalWrite(6,0);
    digitalWrite(7,0);
  }
  else{
    if (b==555){          //刹车
      digitalWrite(6,1);
      digitalWrite(7,1);
    }
    else{
      if (b>0){
      analogWrite(6,b);
      digitalWrite(7,0);
      }
      else{
      analogWrite(6,b-255);
      digitalWrite(7,1);
      }
    }
  } 
}
int incomedate = 0; //串口数据变量
int P1,P2,P3; //左,中,右传感器模拟值
int S1,S2,S3; //左,中,右传感器数字值
int leftspeed,rightspeed; //左马达速度,右马达速度
int V=110; //基础巡线速度
int PID_P=8; //pid  p参数
int ZuoYou=1;  //0左 1右 黑线的左右
int slow=55;   //摇摆巡线慢速
int fast=130;   //摇摆巡线快速


void setup()
{
    pinMode(13,OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(1, OUTPUT);
    pinMode(2, OUTPUT);
    Serial.begin(9600); //设置串口波特率9600
    digitalWrite(13,0);

    digitalWrite(1,0);  //P1 指示灯
    digitalWrite(2,0);  //P3 指示灯
    delay(3000);
}

void loop() 
{
  //digitalWrite(13,1);
  //Serial.println(analogRead(A4));
  while(1)
    {
      ReadGray();
      if (ZuoYou==1) //沿线右侧走
      {
        ReadGray();
        if (S3==1)
         {
          ZuoYou=0;
          continue;
         } 
        else
        {
          if (S2==1)  //黑线上
          {
            go(fast,slow+5);
          }
          else
          {
            go(slow,fast+5);
          }
        }
      }
      else
      {
        ReadGray();
        if (S1==1)
         {
          ZuoYou=1;
          continue;
         } 
        else
        {
          if (S2==1)  //黑线上
          {
            go(slow,fast+5);
          }
          else
          {
            go(fast,slow+5);
          }
        }
      }
    }
  go(leftspeed,rightspeed);
}

评论

user-avatar
  • 肆意march

    肆意march2023.10.13

    亲亲。可以指导机器人制作吗,可以有偿,真的很需要帮助

    0
    • 杨添淮

      杨添淮2022.12.29

      0
      • 虾虾^0^

        虾虾^0^2021.08.12

        厉害

        0